home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / MDB / Common.php next >
PHP Script  |  2004-03-24  |  157KB  |  4,522 lines

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP Version 4                                                        |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
  6. // | Stig. S. Bakken, Lukas Smith                                         |
  7. // | All rights reserved.                                                 |
  8. // +----------------------------------------------------------------------+
  9. // | MDB is a merge of PEAR DB and Metabases that provides a unified DB   |
  10. // | API as well as database abstraction for PHP applications.            |
  11. // | This LICENSE is in the BSD license style.                            |
  12. // |                                                                      |
  13. // | Redistribution and use in source and binary forms, with or without   |
  14. // | modification, are permitted provided that the following conditions   |
  15. // | are met:                                                             |
  16. // |                                                                      |
  17. // | Redistributions of source code must retain the above copyright       |
  18. // | notice, this list of conditions and the following disclaimer.        |
  19. // |                                                                      |
  20. // | Redistributions in binary form must reproduce the above copyright    |
  21. // | notice, this list of conditions and the following disclaimer in the  |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // |                                                                      |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission.                                                  |
  28. // |                                                                      |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  40. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Lukas Smith <smith@backendmedia.com>                         |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id: Common.php,v 1.114.4.11 2004/01/08 13:43:02 lsmith Exp $
  46.  
  47. /**
  48.  * @package MDB
  49.  * @author Lukas Smith <smith@backendmedia.com>
  50.  */
  51.  
  52. // }}}
  53. // {{{ MDB_defaultDebugOutput()
  54.  
  55. /**
  56.  * default debug output handler
  57.  *
  58.  * @param object $db reference to an MDB database object
  59.  * @param string $message message that should be appended to the debug
  60.  *       variable
  61.  * @return string the corresponding error message, of FALSE
  62.  * if the error code was unknown
  63.  * @access public
  64.  */
  65. function MDB_defaultDebugOutput(&$db, $message)
  66. {
  67.     $db->debug_output .= $db->database . " $message" . $db->getOption('log_line_break');
  68. }
  69.  
  70. /**
  71.  * MDB_Common: Base class that is extended by each MDB driver
  72.  *
  73.  * @package MDB
  74.  * @category Database
  75.  * @author Lukas Smith <smith@backendmedia.com>
  76.  */
  77. class MDB_Common extends PEAR
  78. {
  79.     // {{{ properties
  80.     /**
  81.     * index of the MDB object withing the global $_MDB_databases array
  82.     * @var integer
  83.     * @access private
  84.     */
  85.     var $database = 0;
  86.  
  87.     /**
  88.     * @var string
  89.     * @access private
  90.     */
  91.     var $host = '';
  92.  
  93.     /**
  94.     * @var string
  95.     * @access private
  96.     */
  97.     var $port = '';
  98.  
  99.     /**
  100.     * @var string
  101.     * @access private
  102.     */
  103.     var $user = '';
  104.  
  105.     /**
  106.     * @var string
  107.     * @access private
  108.     */
  109.     var $password = '';
  110.  
  111.     /**
  112.     * @var string
  113.     * @access private
  114.     */
  115.     var $database_name = '';
  116.  
  117.     /**
  118.     * @var array
  119.     * @access private
  120.     */
  121.     var $supported = array();
  122.  
  123.     /**
  124.     * $options["persistent"] -> boolean persistent connection true|false?
  125.     * $options["debug"] -> integer numeric debug level
  126.     * $options["autofree"] -> boolean
  127.     * $options["lob_buffer_length"] -> integer LOB buffer length
  128.     * $options["log_line_break"] -> string line-break format
  129.     * $options["seqname_format"] -> string pattern for sequence name
  130.     * $options["includelob"] -> boolean
  131.     * $options["includemanager"] -> boolean
  132.     * $options["UseTransactions"] -> boolean
  133.     * $options["optimize"] -> string 'performance' or 'portability'
  134.     * @var array
  135.     * @access private
  136.     */
  137.     var $options = array(
  138.             'persistent' => FALSE,
  139.             'debug' => FALSE,
  140.             'autofree' => FALSE,
  141.             'lob_buffer_length' => 8192,
  142.             'log_line_break' => "\n",
  143.             'seqname_format' => '%s_seq',
  144.             'includelob' => FALSE,
  145.             'includemanager' => FALSE,
  146.             'UseTransactions' => FALSE,
  147.             'optimize' => 'performance',
  148.         );
  149.  
  150.     /**
  151.     * @var string
  152.     * @access private
  153.     */
  154.     var $escape_quotes = '';
  155.  
  156.     /**
  157.     * @var integer
  158.     * @access private
  159.     */
  160.     var $decimal_places = 2;
  161.  
  162.     /**
  163.     * @var string
  164.     * @access private
  165.     */
  166.     var $manager_included_constant = '';
  167.  
  168.     /**
  169.     * @var string
  170.     * @access private
  171.     */
  172.     var $manager_include = '';
  173.  
  174.     /**
  175.     * @var string
  176.     * @access private
  177.     */
  178.     var $manager_class_name = '';
  179.  
  180.     /**
  181.     * @var object
  182.     * @access private
  183.     */
  184.     var $manager;
  185.  
  186.     /**
  187.     * @var array
  188.     * @access private
  189.     */
  190.     var $warnings = array();
  191.  
  192.     /**
  193.     * @var string
  194.     * @access private
  195.     */
  196.     var $debug = '';
  197.  
  198.     /**
  199.     * @var string
  200.     * @access private
  201.     */
  202.     var $debug_output = '';
  203.  
  204.     /**
  205.     * @var boolean
  206.     * @access private
  207.     */
  208.     var $pass_debug_handle = FALSE;
  209.  
  210.     /**
  211.     * @var boolean
  212.     * @access private
  213.     */
  214.     var $auto_commit = TRUE;
  215.  
  216.     /**
  217.     * @var boolean
  218.     * @access private
  219.     */
  220.     var $in_transaction = FALSE;
  221.  
  222.     /**
  223.     * @var integer
  224.     * @access private
  225.     */
  226.     var $first_selected_row = 0;
  227.  
  228.     /**
  229.     * @var integer
  230.     * @access private
  231.     */
  232.     var $selected_row_limit = 0;
  233.  
  234.     /**
  235.     * DB type (mysql, oci8, odbc etc.)
  236.     * @var string
  237.     * @access private
  238.     */
  239.     var $type;
  240.  
  241.     /**
  242.     * @var array
  243.     * @access private
  244.     */
  245.     var $prepared_queries = array();
  246.  
  247.     /**
  248.     * @var array
  249.     * @access private
  250.     */
  251.     var $result_types;
  252.  
  253.     /**
  254.     * @var string
  255.     * @access private
  256.     */
  257.     var $last_query = '';
  258.  
  259.     /**
  260.     * @var integer
  261.     * @access private
  262.     */
  263.     var $fetchmode = MDB_FETCHMODE_ORDERED;
  264.  
  265.     /**
  266.     * @var integer
  267.     * @access private
  268.     */
  269.     var $affected_rows = -1;
  270.  
  271.     /**
  272.     * @var array
  273.     * @access private
  274.     */
  275.     var $lobs = array();
  276.  
  277.     /**
  278.     * @var array
  279.     * @access private
  280.     */
  281.     var $clobs = array();
  282.  
  283.     /**
  284.     * @var array
  285.     * @access private
  286.     */
  287.     var $blobs = array();
  288.  
  289.     // }}}
  290.     // {{{ constructor
  291.  
  292.     /**
  293.      * Constructor
  294.      */
  295.     function MDB_Common()
  296.     {
  297.         $database = count($GLOBALS['_MDB_databases']) + 1;
  298.         $GLOBALS['_MDB_databases'][$database] = &$this;
  299.         $this->database = $database;
  300.  
  301.         $this->PEAR('MDB_Error');
  302.         $this->supported = array();
  303.         $this->errorcode_map = array();
  304.         $this->fetchmode = MDB_FETCHMODE_ORDERED;
  305.     }
  306.  
  307.     // }}}
  308.     // {{{ _toString()
  309.  
  310.     /**
  311.      * String conversation
  312.      *
  313.      * @return string
  314.      * @access private
  315.      */
  316.     function _toString()
  317.     {
  318.         $info = get_class($this);
  319.         $info .= ': (phptype = ' . $this->phptype . ', dbsyntax = ' . $this->dbsyntax . ')';
  320.         if ($this->connection) {
  321.             $info .= ' [connected]';
  322.         }
  323.         return($info);
  324.     }
  325.  
  326.     // }}}
  327.     // {{{ errorCode()
  328.  
  329.     /**
  330.      * Map native error codes to MDB's portable ones.  Requires that
  331.      * the DB implementation's constructor fills in the $errorcode_map
  332.      * property.
  333.      *
  334.      * @param mixed $nativecode the native error code, as returned by the
  335.      *      backend database extension (string or integer)
  336.      * @return int a portable MDB error code, or FALSE if this MDB
  337.      *      implementation has no mapping for the given error code.
  338.      * @access public
  339.      */
  340.     function errorCode($nativecode)
  341.     {
  342.         if (isset($this->errorcode_map[$nativecode])) {
  343.             return($this->errorcode_map[$nativecode]);
  344.         }
  345.         // Fall back to MDB_ERROR if there was no mapping.
  346.         return(MDB_ERROR);
  347.     }
  348.  
  349.     // }}}
  350.     // {{{ errorMessage()
  351.  
  352.     /**
  353.      * Map a MDB error code to a textual message.  This is actually
  354.      * just a wrapper for MDB::errorMessage().
  355.      *
  356.      * @param integer $dbcode the MDB error code
  357.      * @return string the corresponding error message, of FALSE
  358.      *      if the error code was unknown
  359.      * @access public
  360.      */
  361.     function errorMessage($dbcode)
  362.     {
  363.         return(MDB::errorMessage($this->errorcode_map[$dbcode]));
  364.     }
  365.  
  366.     // }}}
  367.     // {{{ raiseError()
  368.  
  369.     /**
  370.      * This method is used to communicate an error and invoke error
  371.      * callbacks etc.  Basically a wrapper for PEAR::raiseError
  372.      * without the message string.
  373.      *
  374.      * @param mixed $code integer error code, or a PEAR error object (all
  375.      *      other parameters are ignored if this parameter is an object
  376.      * @param int $mode error mode, see PEAR_Error docs
  377.      * @param mixed $options If error mode is PEAR_ERROR_TRIGGER, this is the
  378.      *      error level (E_USER_NOTICE etc).  If error mode is
  379.      *      PEAR_ERROR_CALLBACK, this is the callback function, either as a
  380.      *      function name, or as an array of an object and method name. For
  381.      *      other error modes this parameter is ignored.
  382.      * @param string $userinfo Extra debug information.  Defaults to the last
  383.      *      query and native error code.
  384.      * @param mixed $nativecode Native error code, integer or string depending
  385.      *      the backend.
  386.      * @return object a PEAR error object
  387.      * @access public
  388.      * @see PEAR_Error
  389.      */
  390.     function &raiseError($code = MDB_ERROR, $mode = NULL, $options = NULL,
  391.         $userinfo = NULL, $nativecode = NULL)
  392.     {
  393.         // The error is yet a MDB error object
  394.         if (is_object($code)) {
  395.             $err = PEAR::raiseError($code, NULL, NULL, NULL, NULL, NULL, TRUE);
  396.             return($err);
  397.         }
  398.  
  399.         if ($userinfo === NULL) {
  400.             $userinfo = $this->last_query;
  401.         }
  402.  
  403.         if ($nativecode) {
  404.             $userinfo .= " [nativecode = $nativecode]";
  405.         }
  406.  
  407.         $err = PEAR::raiseError(NULL, $code, $mode, $options, $userinfo, 'MDB_Error', TRUE);
  408.         return($err);
  409.     }
  410.  
  411.     // }}}
  412.     // {{{ errorNative()
  413.  
  414.     /**
  415.      * returns an errormessage, provides by the database
  416.      *
  417.      * @return mixed MDB_Error or message
  418.      * @access public
  419.      */
  420.     function errorNative()
  421.     {
  422.         return($this->raiseError(MDB_ERROR_NOT_CAPABLE));
  423.     }
  424.  
  425.     // }}}
  426.     // {{{ resetWarnings()
  427.  
  428.     /**
  429.      * reset the warning array
  430.      *
  431.      * @access public
  432.      */
  433.     function resetWarnings()
  434.     {
  435.         $this->warnings = array();
  436.     }
  437.  
  438.     // }}}
  439.     // {{{ getWarnings()
  440.  
  441.     /**
  442.      * get all warnings in reverse order.
  443.      * This means that the last warning is the first element in the array
  444.      *
  445.      * @return array with warnings
  446.      * @access public
  447.      * @see resetWarnings()
  448.      */
  449.     function getWarnings()
  450.     {
  451.         return array_reverse($this->warnings);
  452.     }
  453.  
  454.     // }}}
  455.     // {{{ setOption()
  456.  
  457.     /**
  458.      * set the option for the db class
  459.      *
  460.      * @param string $option option name
  461.      * @param mixed $value value for the option
  462.      * @return mixed MDB_OK or MDB_Error
  463.      * @access public
  464.      */
  465.     function setOption($option, $value)
  466.     {
  467.         if (isset($this->options[$option])) {
  468.             $this->options[$option] = $value;
  469.             return MDB_OK;
  470.         }
  471.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
  472.     }
  473.  
  474.     // }}}
  475.     // {{{ getOption()
  476.  
  477.     /**
  478.      * returns the value of an option
  479.      *
  480.      * @param string $option option name
  481.      * @return mixed the option value or error object
  482.      * @access public
  483.      */
  484.     function getOption($option)
  485.     {
  486.         if (isset($this->options[$option])) {
  487.             return($this->options[$option]);
  488.         }
  489.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
  490.     }
  491.  
  492.     // }}}
  493.     // {{{ captureDebugOutput()
  494.  
  495.     /**
  496.      * set a debug handler
  497.      *
  498.      * @param string $capture name of the function that should be used in
  499.      *      debug()
  500.      * @access public
  501.      * @see debug()
  502.      */
  503.     function captureDebugOutput($capture)
  504.     {
  505.         $this->pass_debug_handle = $capture;
  506.         $this->debug = ($capture ? 'MDB_defaultDebugOutput' : '');
  507.     }
  508.  
  509.     // }}}
  510.     // {{{ debug()
  511.  
  512.     /**
  513.      * set a debug message
  514.      *
  515.      * @param string $message Message with information for the user.
  516.      * @access public
  517.      */
  518.     function debug($message)
  519.     {
  520.         if (strcmp($function = $this->debug, '')) {
  521.             if ($this->pass_debug_handle) {
  522.                 $function($this, $message);
  523.             } else {
  524.                 $function($message);
  525.             }
  526.         }
  527.     }
  528.  
  529.     // }}}
  530.     // {{{ debugOutput()
  531.  
  532.     /**
  533.      * output debug info
  534.      *
  535.      * @return string content of the debug_output class variable
  536.      * @access public
  537.      */
  538.     function debugOutput()
  539.     {
  540.         return($this->debug_output);
  541.     }
  542.  
  543.     // }}}
  544.     // {{{ setError() (deprecated)
  545.  
  546.     /**
  547.      * set an error (deprecated)
  548.      *
  549.      * @param string $scope Scope of the error message
  550.      *     (usually the method tht caused the error)
  551.      * @param string $message Message with information for the user.
  552.      * @return boolean FALSE
  553.      * @access private
  554.      */
  555.     function setError($scope, $message)
  556.     {
  557.         $this->last_error = $message;
  558.         $this->debug($scope . ': ' . $message);
  559.         if (($function = $this->error_handler) != '') {
  560.             $error = array(
  561.                 'Scope' => $scope,
  562.                 'Message' => $message
  563.             );
  564.             $function($this, $error);
  565.         }
  566.         return(0);
  567.     }
  568.  
  569.     // }}}
  570.     // {{{ setErrorHandler() (deprecated)
  571.  
  572.     /**
  573.      * Specify a function that is called when an error occurs.
  574.      *
  575.      * @param string $function Name of the function that will be called on
  576.      *      error. If an empty string is specified, no handler function is
  577.      *      called on error. The error handler function receives two arguments.
  578.      *      The first argument a reference to the driver class object that
  579.      *      triggered the error.
  580.      *
  581.      *      The second argument is a reference to an associative array that
  582.      *      provides details about the error that occured. These details provide
  583.      *      more information than it is returned by the MetabaseError function.
  584.      *
  585.      *      These are the currently supported error detail entries:
  586.      *
  587.      *      Scope
  588.      *       String that indicates the scope of the driver object class
  589.      *       within which the error occured.
  590.      *
  591.      *      Message
  592.      *       Error message as is returned by the MetabaseError function.
  593.      * @return string name of last function
  594.      * @access public
  595.      */
  596.     function setErrorHandler($function)
  597.     {
  598.         $last_function = $this->error_handler;
  599.         $this->error_handler = $function;
  600.         return($last_function);
  601.     }
  602.  
  603.     // }}}
  604.     // {{{ error() (deprecated)
  605.  
  606.     /**
  607.      * Retrieve the error message text associated with the last operation that
  608.      * failed. Some functions may fail but they do not return the reason that
  609.      * makes them to fail. This function is meant to retrieve a textual
  610.      * description of the failure cause.
  611.      *
  612.      * @return string the error message text associated with the last failure.
  613.      * @access public
  614.      */
  615.     function error()
  616.     {
  617.         return($this->last_error);
  618.     }
  619.  
  620.     // }}}
  621.     // {{{ _quote()
  622.  
  623.     /**
  624.      * Quotes a string so it can be safely used in a query. It will quote
  625.      * the text so it can safely be used within a query.
  626.      *
  627.      * @param string $text the input string to quote
  628.      * @return string quoted string
  629.      * @access private
  630.      */
  631.     function _quote($text)
  632.     {
  633.         if (strcmp($this->escape_quotes, "'")) {
  634.             $text = str_replace($this->escape_quotes, $this->escape_quotes . $this->escape_quotes, $text);
  635.         }
  636.         return str_replace("'", $this->escape_quotes . "'", $text);
  637.     }
  638.  
  639.     // }}}
  640.     // {{{ _loadModule()
  641.  
  642.     /**
  643.      * loads an module
  644.      *
  645.      * @param string $scope information about what method is being loaded,
  646.      *      that is used for error messages
  647.      * @param string $module name of the module that should be loaded
  648.      *      (only used for error messages)
  649.      * @param string $included_constant name of the constant that should be
  650.      *      defined when the module has been loaded
  651.      * @param string $include name of the script that includes the module
  652.      * @access private
  653.      */
  654.     function _loadModule($scope, $module, $included_constant, $include)
  655.     {
  656.         if (strlen($included_constant) == 0 || !defined($included_constant)) {
  657.             if($include) {
  658.                 $include = 'MDB/Modules/'.$include;
  659.                 if(MDB::isError($debug = $this->getOption('debug')) || $debug > 2) {
  660.                     include_once($include);
  661.                 } else {
  662.                     @include_once($include);
  663.                 }
  664.             } else {
  665.                 return($this->raiseError(MDB_ERROR_LOADMODULE, NULL, NULL,
  666.                     $scope . ': it was not specified an existing ' . $module . ' file (' . $include . ')'));
  667.             }
  668.         }
  669.         return(MDB_OK);
  670.     }
  671.  
  672.     // }}}
  673.     // {{{ loadLob()
  674.  
  675.     /**
  676.      * loads the LOB module
  677.      *
  678.      * @param string $scope information about what method is being loaded,
  679.      *                       that is used for error messages
  680.      * @access public
  681.      */
  682.     function loadLob($scope = '')
  683.     {
  684.         if (defined('MDB_LOB_INCLUDED')) {
  685.             return(MDB_OK);
  686.         }
  687.         $result = $this->_loadModule($scope, 'LOB',
  688.             'MDB_LOB_INCLUDED', 'LOB.php');
  689.         if (MDB::isError($result)) {
  690.             return($result);
  691.         }
  692.         return(MDB_OK);
  693.     }
  694.  
  695.     // }}}
  696.     // {{{ loadManager()
  697.  
  698.     /**
  699.      * loads the Manager module
  700.      *
  701.      * @param string $scope information about what method is being loaded,
  702.      *                       that is used for error messages
  703.      * @access public
  704.      */
  705.     function loadManager($scope = '')
  706.     {
  707.         if (isset($this->manager) && is_object($this->manager)) {
  708.             return(MDB_OK);
  709.         }
  710.         $result = $this->_loadModule($scope, 'Manager',
  711.             'MDB_MANAGER_'.strtoupper($this->phptype).'_INCLUDED',
  712.             'Manager/'.$this->phptype.'.php');
  713.         if (MDB::isError($result)) {
  714.             return($result);
  715.         }
  716.         $class_name = 'MDB_Manager_'.$this->dbsyntax;
  717.         if (!class_exists($class_name)) {
  718.             return($this->raiseError(MDB_ERROR_LOADMODULE, NULL, NULL,
  719.                 'Unable to load extension'));
  720.         }
  721.         @$this->manager = new $class_name;
  722.         return(MDB_OK);
  723.     }
  724.  
  725.     // }}}
  726.     // {{{ autoCommit()
  727.  
  728.     /**
  729.      * Define whether database changes done on the database be automatically
  730.      * committed. This function may also implicitly start or end a transaction.
  731.      *
  732.      * @param boolean $auto_commit flag that indicates whether the database
  733.      *      changes should be committed right after executing every query
  734.      *      statement. If this argument is 0 a transaction implicitly started.
  735.      *      Otherwise, if a transaction is in progress it is ended by committing
  736.      *      any database changes that were pending.
  737.      * @return mixed MDB_OK on success, a MDB error on failure
  738.      * @access public
  739.      */
  740.     function autoCommit($auto_commit)
  741.     {
  742.         $this->debug('AutoCommit: ' . ($auto_commit ? 'On' : 'Off'));
  743.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  744.             'Auto-commit transactions: transactions are not supported'));
  745.     }
  746.  
  747.     // }}}
  748.     // {{{ commit()
  749.  
  750.     /**
  751.      * Commit the database changes done during a transaction that is in
  752.      * progress. This function may only be called when auto-committing is
  753.      * disabled, otherwise it will fail. Therefore, a new transaction is
  754.      * implicitly started after committing the pending changes.
  755.      *
  756.      * @return mixed MDB_OK on success, a MDB error on failure
  757.      * @access public
  758.      */
  759.     function commit()
  760.     {
  761.         $this->debug('Commit Transaction');
  762.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  763.             'Commit transaction: commiting transactions are not supported'));
  764.     }
  765.  
  766.     // }}}
  767.     // {{{ rollback()
  768.  
  769.     /**
  770.      * Cancel any database changes done during a transaction that is in
  771.      * progress. This function may only be called when auto-committing is
  772.      * disabled, otherwise it will fail. Therefore, a new transaction is
  773.      * implicitly started after canceling the pending changes.
  774.      *
  775.      * @return mixed MDB_OK on success, a MDB error on failure
  776.      * @access public
  777.      */
  778.     function rollback()
  779.     {
  780.         $this->debug('Rollback Transaction');
  781.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  782.             'Rollback transaction: rolling back transactions are not supported'));
  783.     }
  784.  
  785.     // }}}
  786.     // {{{ disconnect()
  787.  
  788.     /**
  789.      * Log out and disconnect from the database.
  790.      *
  791.      * @return mixed TRUE on success, FALSE if not connected and error
  792.      *                object on error
  793.      * @access public
  794.      */
  795.     function disconnect()
  796.     {
  797.         if ($this->in_transaction && !MDB::isError($this->rollback()) && !MDB::isError($this->autoCommit(TRUE))) {
  798.             $this->in_transaction = FALSE;
  799.         }
  800.         return($this->_close());
  801.     }
  802.  
  803.     // }}}
  804.     // {{{ _close()
  805.  
  806.     /**
  807.      * all the RDBMS specific things needed to close a DB connection
  808.      *
  809.      * @access private
  810.      */
  811.     function _close()
  812.     {
  813.         unset($GLOBALS['_MDB_databases'][$this->database]);
  814.     }
  815.  
  816.     // }}}
  817.     // {{{ setDatabase()
  818.  
  819.     /**
  820.      * Select a different database
  821.      *
  822.      * @param string $name name of the database that should be selected
  823.      * @return string name of the database previously connected to
  824.      * @access public
  825.      */
  826.     function setDatabase($name)
  827.     {
  828.         $previous_database_name = $this->database_name;
  829.         $this->database_name = $name;
  830.         return($previous_database_name);
  831.     }
  832.  
  833.     // }}}
  834.     // {{{ setDSN()
  835.  
  836.     /**
  837.      * set the DSN
  838.      *
  839.      * @param mixed     $dsninfo    DSN string or array
  840.      * @return MDB_OK
  841.      * @access public
  842.      */
  843.     function setDSN($dsn)
  844.     {
  845.         $dsninfo = MDB::parseDSN($dsn);
  846.         if(isset($dsninfo['hostspec'])) {
  847.             $this->host = $dsninfo['hostspec'];
  848.         }
  849.         if(isset($dsninfo['port'])) {
  850.             $this->port = $dsninfo['port'];
  851.         }
  852.         if(isset($dsninfo['username'])) {
  853.             $this->user = $dsninfo['username'];
  854.         }
  855.         if(isset($dsninfo['password'])) {
  856.             $this->password = $dsninfo['password'];
  857.         }
  858.         if(isset($dsninfo['database'])) {
  859.             $this->database_name = $dsninfo['database'];
  860.         }
  861.         return(MDB_OK);
  862.     }
  863.  
  864.     // }}}
  865.     // {{{ getDSN()
  866.  
  867.     /**
  868.      * return the DSN as a string
  869.      *
  870.      * @param string     $type    type to return
  871.      * @return mixed DSN in the chosen type
  872.      * @access public
  873.      */
  874.     function getDSN($type = 'string')
  875.     {
  876.         switch($type) {
  877.             case 'array':
  878.                 $dsn = array(
  879.                     'phptype' => $this->phptype,
  880.                     'username' => $this->user,
  881.                     'password' => $this->password,
  882.                     'hostspec' => $this->host,
  883.                     'database' => $this->database_name
  884.                 );
  885.                 break;
  886.             default:
  887.                 $dsn = $this->phptype.'://'.$this->user.':'
  888.                     .$this->password.'@'.$this->host
  889.                     .($this->port ? (':'.$this->port) : '')
  890.                     .'/'.$this->database_name;
  891.                 break;
  892.         }
  893.         return($dsn);
  894.     }
  895.  
  896.     // }}}
  897.     // {{{ createDatabase()
  898.  
  899.     /**
  900.      * create a new database
  901.      *
  902.      * @param string $name name of the database that should be created
  903.      * @return mixed MDB_OK on success, a MDB error on failure
  904.      * @access public
  905.      */
  906.     function createDatabase($name)
  907.     {
  908.         $result = $this->loadManager('Create database');
  909.         if (MDB::isError($result)) {
  910.             return($result);
  911.         }
  912.         return($this->manager->createDatabase($this, $name));
  913.     }
  914.  
  915.     // }}}
  916.     // {{{ dropDatabase()
  917.  
  918.     /**
  919.      * drop an existing database
  920.      *
  921.      * @param string $name name of the database that should be dropped
  922.      * @return mixed MDB_OK on success, a MDB error on failure
  923.      * @access public
  924.      */
  925.     function dropDatabase($name)
  926.     {
  927.         $result = $this->loadManager('Drop database');
  928.         if (MDB::isError($result)) {
  929.             return($result);
  930.         }
  931.         return($this->manager->dropDatabase($this, $name));
  932.     }
  933.  
  934.     // }}}
  935.     // {{{ createTable()
  936.  
  937.     /**
  938.      * create a new table
  939.      *
  940.      * @param string $name Name of the database that should be created
  941.      * @param array $fields Associative array that contains the definition of
  942.      *      each field of the new table. The indexes of the array entries are
  943.      *      the names of the fields of the table an the array entry values are
  944.      *      associative arrays like those that are meant to be passed with the
  945.      *      field definitions to get[Type]Declaration() functions.
  946.      *
  947.      *      Example
  948.      *        array(
  949.      *            'id' => array(
  950.      *                'type' => 'integer',
  951.      *                'unsigned' => 1
  952.      *                'notnull' => 1
  953.      *                'default' => 0
  954.      *            ),
  955.      *            'name' => array(
  956.      *                'type' => 'text',
  957.      *                'length' => 12
  958.      *            ),
  959.      *            'password' => array(
  960.      *                'type' => 'text',
  961.      *                'length' => 12
  962.      *            )
  963.      *        );
  964.      * @return mixed MDB_OK on success, a MDB error on failure
  965.      * @access public
  966.      */
  967.     function createTable($name, $fields)
  968.     {
  969.         $result = $this->loadManager('Create table');
  970.         if (MDB::isError($result)) {
  971.             return($result);
  972.         }
  973.         return($this->manager->createTable($this, $name, $fields));
  974.     }
  975.  
  976.     // }}}
  977.     // {{{ dropTable()
  978.  
  979.     /**
  980.      * drop an existing table
  981.      *
  982.      * @param string $name name of the table that should be dropped
  983.      * @return mixed MDB_OK on success, a MDB error on failure
  984.      * @access public
  985.      */
  986.     function dropTable($name)
  987.     {
  988.         $result = $this->loadManager('Drop table');
  989.         if (MDB::isError($result)) {
  990.             return($result);
  991.         }
  992.         return($this->manager->dropTable($this, $name));
  993.     }
  994.  
  995.     // }}}
  996.     // {{{ alterTable()
  997.  
  998.     /**
  999.      * alter an existing table
  1000.      *
  1001.      * @param string $name name of the table that is intended to be changed.
  1002.      * @param array  $changes associative array that contains the details of
  1003.      *       each type of change that is intended to be performed. The types of
  1004.      *       changes that are currently supported are defined as follows:
  1005.      *
  1006.      *  name
  1007.      *      New name for the table.
  1008.      *
  1009.      *  AddedFields
  1010.      *      Associative array with the names of fields to be added as indexes of
  1011.      *      the array. The value of each entry of the array should be set to
  1012.      *      another associative array with the properties of the fields to be
  1013.      *      added. The properties of the fields should be the same as defined by
  1014.      *      the Metabase parser.
  1015.      *
  1016.      *      Additionally, there should be an entry named Declaration that is
  1017.      *      expected to contain the portion of the field declaration already in
  1018.      *       DBMS specific SQL code as it is used in the CREATE TABLE statement.
  1019.      *
  1020.      *  RemovedFields
  1021.      *      Associative array with the names of fields to be removed as indexes of
  1022.      *      the array. Currently the values assigned to each entry are ignored. An
  1023.      *      empty array should be used for future compatibility.
  1024.      *
  1025.      *  RenamedFields
  1026.      *      Associative array with the names of fields to be renamed as indexes of
  1027.      *      the array. The value of each entry of the array should be set to another
  1028.      *      associative array with the entry named name with the new field name and
  1029.      *      the entry named Declaration that is expected to contain the portion of
  1030.      *      the field declaration already in DBMS specific SQL code as it is used
  1031.      *      in the CREATE TABLE statement.
  1032.      *
  1033.      *  ChangedFields
  1034.      *      Associative array with the names of the fields to be changed as indexes
  1035.      *      of the array. Keep in mind that if it is intended to change either the
  1036.      *      name of a field and any other properties, the ChangedFields array
  1037.      *      entries should have the new names of the fields as array indexes.
  1038.      *
  1039.      *      The value of each entry of the array should be set to another
  1040.      *      associative array with the properties of the fields to that are meant
  1041.      *      to be changed as array entries. These entries should be assigned to the
  1042.      *      new values of the respective properties. The properties of the fields
  1043.      *      should be the* same as defined by the Metabase parser.
  1044.      *
  1045.      *      If the default property is meant to be added, removed or changed, there
  1046.      *      should also be an entry with index ChangedDefault assigned to 1.
  1047.      *      Similarly, if the notnull constraint is to be added or removed, there
  1048.      *      should also be an entry with index ChangedNotNull assigned to 1.
  1049.      *
  1050.      *      Additionally, there should be an entry named Declaration that is
  1051.      *      expected to contain the portion of the field changed declaration
  1052.      *      already in DBMS specific SQL code as it is used in the CREATE TABLE
  1053.      *      statement.
  1054.      *
  1055.      *  Example
  1056.      *      array(
  1057.      *          'name' => 'userlist',
  1058.      *          'AddedFields' => array(
  1059.      *              'quota' => array(
  1060.      *                  'type' => 'integer',
  1061.      *                  'unsigned' => 1,
  1062.      *                  'Declaration' => 'quota INT'
  1063.      *              )
  1064.      *          ),
  1065.      *          'RemovedFields' => array(
  1066.      *              'file_limit' => array(),
  1067.      *              'time_limit' => array()
  1068.      *          ),
  1069.      *          'ChangedFields' => array(
  1070.      *              'gender' => array(
  1071.      *                  'default' => 'M',
  1072.      *                  'ChangeDefault' => 1,
  1073.      *                  'Declaration' => "gender CHAR(1) DEFAULT 'M'"
  1074.      *              )
  1075.      *          ),
  1076.      *          'RenamedFields' => array(
  1077.      *              'sex' => array(
  1078.      *                  'name' => 'gender',
  1079.      *                  'Declaration' => "gender CHAR(1) DEFAULT 'M'"
  1080.      *              )
  1081.      *          )
  1082.      *      )
  1083.      *
  1084.      * @param boolean $check indicates whether the function should just check
  1085.      *       if the DBMS driver can perform the requested table alterations if
  1086.      *       the value is TRUE or actually perform them otherwise.
  1087.      * @return mixed MDB_OK on success, a MDB error on failure
  1088.      * @access public
  1089.      */
  1090.     function alterTable($name, $changes, $check)
  1091.     {
  1092.         $result = $this->loadManager('Alter table');
  1093.         if (MDB::isError($result)) {
  1094.             return($result);
  1095.         }
  1096.         return($this->manager->alterTable($this, $name, $changes, $check));
  1097.     }
  1098.  
  1099.     // }}}
  1100.     // {{{ listDatabases()
  1101.  
  1102.     /**
  1103.      * list all databases
  1104.      *
  1105.      * @return mixed data array on success, a MDB error on failure
  1106.      * @access public
  1107.      */
  1108.     function listDatabases()
  1109.     {
  1110.         $result = $this->loadManager('List databases');
  1111.         if (MDB::isError($result)) {
  1112.             return($result);
  1113.         }
  1114.         return($this->manager->listDatabases($this));
  1115.     }
  1116.  
  1117.     // }}}
  1118.     // {{{ listUsers()
  1119.  
  1120.     /**
  1121.      * list all users
  1122.      *
  1123.      * @return mixed data array on success, a MDB error on failure
  1124.      * @access public
  1125.      */
  1126.     function listUsers()
  1127.     {
  1128.         $result = $this->loadManager('List users');
  1129.         if (MDB::isError($result)) {
  1130.             return($result);
  1131.         }
  1132.         return($this->manager->listUsers($this));
  1133.     }
  1134.  
  1135.     // }}}
  1136.     // {{{ listViews()
  1137.  
  1138.     /**
  1139.      * list all viewes in the current database
  1140.      *
  1141.      * @return mixed data array on success, a MDB error on failure
  1142.      * @access public
  1143.      */
  1144.     function listViews()
  1145.     {
  1146.         $result = $this->loadManager('List views');
  1147.         if (MDB::isError($result)) {
  1148.             return($result);
  1149.         }
  1150.         return($this->manager->listViews($this));
  1151.     }
  1152.  
  1153.     // }}}
  1154.     // {{{ listFunctions()
  1155.  
  1156.     /**
  1157.      * list all functions in the current database
  1158.      *
  1159.      * @return mixed data array on success, a MDB error on failure
  1160.      * @access public
  1161.      */
  1162.     function listFunctions()
  1163.     {
  1164.         $result = $this->loadManager('List functions');
  1165.         if (MDB::isError($result)) {
  1166.             return($result);
  1167.         }
  1168.         return($this->manager->listFunctions($this));
  1169.     }
  1170.  
  1171.     // }}}
  1172.     // {{{ listTables()
  1173.  
  1174.     /**
  1175.      * list all tables in the current database
  1176.      *
  1177.      * @return mixed data array on success, a MDB error on failure
  1178.      * @access public
  1179.      */
  1180.     function listTables()
  1181.     {
  1182.         $result = $this->loadManager('List tables');
  1183.         if (MDB::isError($result)) {
  1184.             return($result);
  1185.         }
  1186.         return($this->manager->listTables($this));
  1187.     }
  1188.  
  1189.     // }}}
  1190.     // {{{ listTableFields()
  1191.  
  1192.     /**
  1193.      * list all fields in a tables in the current database
  1194.      *
  1195.      * @param string $table name of table that should be used in method
  1196.      * @return mixed data array on success, a MDB error on failure
  1197.      * @access public
  1198.      */
  1199.     function listTableFields($table)
  1200.     {
  1201.         $result = $this->loadManager('List table fields');
  1202.         if (MDB::isError($result)) {
  1203.             return($result);
  1204.         }
  1205.         return($this->manager->listTableFields($this, $table));
  1206.     }
  1207.  
  1208.     // }}}
  1209.     // {{{ getTableFieldDefinition()
  1210.  
  1211.     /**
  1212.      * get the stucture of a field into an array
  1213.      *
  1214.      * @param string $table name of table that should be used in method
  1215.      * @param string $fields name of field that should be used in method
  1216.      * @return mixed data array on success, a MDB error on failure
  1217.      * @access public
  1218.      */
  1219.     function getTableFieldDefinition($table, $field)
  1220.     {
  1221.         $result = $this->loadManager('Get table field definition');
  1222.         if (MDB::isError($result)) {
  1223.             return($result);
  1224.         }
  1225.         return($this->manager->getTableFieldDefinition($this, $table, $field));
  1226.     }
  1227.  
  1228.     // }}}
  1229.     // {{{ getFieldDeclaration()
  1230.  
  1231.     /**
  1232.      * get declaration of a field
  1233.      *
  1234.      * @param string $field_name name of the field to be created
  1235.      * @param string $field associative array with the name of the properties
  1236.      *       of the field being declared as array indexes. Currently, the types
  1237.      *       of supported field properties are as follows:
  1238.      *
  1239.      *       default
  1240.      *           Boolean value to be used as default for this field.
  1241.      *
  1242.      *       notnull
  1243.      *           Boolean flag that indicates whether this field is constrained
  1244.      *           to not be set to NULL.
  1245.      * @return mixed string on success, a MDB error on failure
  1246.      * @access public
  1247.      */
  1248.     function getFieldDeclaration($field_name, $field)
  1249.     {
  1250.         $result = $this->loadManager('Get table field definition');
  1251.         if (MDB::isError($result)) {
  1252.             return($result);
  1253.         }
  1254.         return($this->manager->getFieldDeclaration($this, $field_name, $field));
  1255.     }
  1256.  
  1257.     // }}}
  1258.     // {{{ getFieldDeclarationList()
  1259.  
  1260.     /**
  1261.      * get declaration of a number of field in bulk
  1262.      *
  1263.      * @param string $fields a multidimensional associative array.
  1264.      * The first dimension determines the field name, while the second
  1265.      * dimension is keyed with the name of the properties
  1266.      *       of the field being declared as array indexes. Currently, the types
  1267.      *       of supported field properties are as follows:
  1268.      *
  1269.      *       default
  1270.      *           Boolean value to be used as default for this field.
  1271.      *
  1272.      *       notnull
  1273.      *           Boolean flag that indicates whether this field is constrained
  1274.      *           to not be set to NULL.
  1275.      *
  1276.      *       default
  1277.      *           Boolean value to be used as default for this field.
  1278.      *
  1279.      *       notnull
  1280.      *           Boolean flag that indicates whether this field is constrained
  1281.      *           to not be set to NULL.
  1282.      * @return mixed string on success, a MDB error on failure
  1283.      * @access public
  1284.      */
  1285.     function getFieldDeclarationList($fields)
  1286.     {
  1287.         $result = $this->loadManager('Get table field list');
  1288.         if (MDB::isError($result)) {
  1289.             return($result);
  1290.         }
  1291.         return($this->manager->getFieldDeclarationList($this, $fields));
  1292.     }
  1293.  
  1294.     // }}}
  1295.     // {{{ _isSequenceName()
  1296.  
  1297.     /**
  1298.      * list all tables in the current database
  1299.      *
  1300.      * @param string $sqn string that containts name of a potential sequence
  1301.      * @return mixed name of the sequence if $sqn is a name of a sequence, else FALSE
  1302.      * @access private
  1303.      */
  1304.     function _isSequenceName($sqn)
  1305.     {
  1306.         $result = $this->loadManager('is sequence name');
  1307.         if (MDB::isError($result)) {
  1308.             return($result);
  1309.         }
  1310.         return($this->manager->_isSequenceName($this, $sqn));
  1311.     }
  1312.  
  1313.     // }}}
  1314.     // {{{ createIndex()
  1315.  
  1316.     /**
  1317.      * get the stucture of a field into an array
  1318.      *
  1319.      * @param string $table name of the table on which the index is to be
  1320.      *       created
  1321.      * @param string $name name of the index to be created
  1322.      * @param array $definition associative array that defines properties of
  1323.      *       the index to be created. Currently, only one property named FIELDS
  1324.      *       is supported. This property is also an associative with the names
  1325.      *       of the index fields as array indexes. Each entry of this array is
  1326.      *       set to another type of associative array that specifies properties
  1327.      *       of the index that are specific to each field.
  1328.      *
  1329.      *       Currently, only the sorting property is supported. It should be
  1330.      *       used to define the sorting direction of the index. It may be set
  1331.      *       to either ascending or descending. Not all DBMS support index
  1332.      *       sorting direction configuration. The DBMS drivers of those that do
  1333.      *       not support it ignore this property. Use the function support() to
  1334.      *       determine whether the DBMS driver can manage indexes.
  1335.      *
  1336.      *       Example
  1337.      *          array(
  1338.      *              'FIELDS' => array(
  1339.      *                  'user_name' => array(
  1340.      *                      'sorting' => 'ascending'
  1341.      *                  ),
  1342.      *                  'last_login' => array()
  1343.      *              )
  1344.      *          )
  1345.      * @return mixed MDB_OK on success, a MDB error on failure
  1346.      * @access public
  1347.      */
  1348.     function createIndex($table, $name, $definition)
  1349.     {
  1350.         $result = $this->loadManager('Create index');
  1351.         if (MDB::isError($result)) {
  1352.             return($result);
  1353.         }
  1354.         return($this->manager->createIndex($this, $table, $name, $definition));
  1355.     }
  1356.  
  1357.     // }}}
  1358.     // {{{ dropIndex()
  1359.  
  1360.     /**
  1361.      * drop existing index
  1362.      *
  1363.      * @param string $table name of table that should be used in method
  1364.      * @param string $name name of the index to be dropped
  1365.      * @return mixed MDB_OK on success, a MDB error on failure
  1366.      * @access public
  1367.      */
  1368.     function dropIndex($table, $name)
  1369.     {
  1370.         $result = $this->loadManager('Drop index');
  1371.         if (MDB::isError($result)) {
  1372.             return($result);
  1373.         }
  1374.         return($this->manager->dropIndex($this, $table , $name));
  1375.     }
  1376.  
  1377.     // }}}
  1378.     // {{{ listTableIndexes()
  1379.  
  1380.     /**
  1381.      * list all indexes in a table
  1382.      *
  1383.      * @param string $table name of table that should be used in method
  1384.      * @return mixed data array on success, a MDB error on failure
  1385.      * @access public
  1386.      */
  1387.     function listTableIndexes($table)
  1388.     {
  1389.         $result = $this->loadManager('List table index');
  1390.         if (MDB::isError($result)) {
  1391.             return($result);
  1392.         }
  1393.         return($this->manager->listTableIndexes($this, $table));
  1394.     }
  1395.  
  1396.     // }}}
  1397.     // {{{ getTableIndexDefinition()
  1398.  
  1399.     /**
  1400.      * get the stucture of an index into an array
  1401.      *
  1402.      * @param string $table name of table that should be used in method
  1403.      * @param string $index name of index that should be used in method
  1404.      * @return mixed data array on success, a MDB error on failure
  1405.      * @access public
  1406.      */
  1407.     function getTableIndexDefinition($table, $index)
  1408.     {
  1409.         $result = $this->loadManager('Get table index definition');
  1410.         if (MDB::isError($result)) {
  1411.             return($result);
  1412.         }
  1413.         return($this->manager->getTableIndexDefinition($this, $table, $index));
  1414.     }
  1415.  
  1416.     // }}}
  1417.     // {{{ createSequence()
  1418.  
  1419.     /**
  1420.      * create sequence
  1421.      *
  1422.      * @param string $name name of the sequence to be created
  1423.      * @param string $start start value of the sequence; default is 1
  1424.      * @return mixed MDB_OK on success, a MDB error on failure
  1425.      * @access public
  1426.      */
  1427.     function createSequence($name, $start = 1)
  1428.     {
  1429.         $result = $this->loadManager('Create sequence');
  1430.         if (MDB::isError($result)) {
  1431.             return($result);
  1432.         }
  1433.         return($this->manager->createSequence($this, $name, $start));
  1434.     }
  1435.  
  1436.     // }}}
  1437.     // {{{ dropSequence()
  1438.  
  1439.     /**
  1440.      * drop existing sequence
  1441.      *
  1442.      * @param string $name name of the sequence to be dropped
  1443.      * @return mixed MDB_OK on success, a MDB error on failure
  1444.      * @access public
  1445.      */
  1446.     function dropSequence($name)
  1447.     {
  1448.         $result = $this->loadManager('Drop sequence');
  1449.         if (MDB::isError($result)) {
  1450.             return($result);
  1451.         }
  1452.         return($this->manager->dropSequence($this, $name));
  1453.     }
  1454.  
  1455.     // }}}
  1456.     // {{{ listSequences()
  1457.  
  1458.     /**
  1459.      * list all tables in the current database
  1460.      *
  1461.      * @return mixed data array on success, a MDB error on failure
  1462.      * @access public
  1463.      */
  1464.     function listSequences()
  1465.     {
  1466.         $result = $this->loadManager('List sequences');
  1467.         if (MDB::isError($result)) {
  1468.             return($result);
  1469.         }
  1470.         return($this->manager->listSequences($this));
  1471.     }
  1472.  
  1473.     // }}}
  1474.     // {{{ getSequenceDefinition()
  1475.  
  1476.     /**
  1477.      * get the stucture of a sequence into an array
  1478.      *
  1479.      * @param string $sequence name of sequence that should be used in method
  1480.      * @return mixed data array on success, a MDB error on failure
  1481.      * @access public
  1482.      */
  1483.     function getSequenceDefinition($sequence)
  1484.     {
  1485.         $result = $this->loadManager('Get sequence definition');
  1486.         if (MDB::isError($result)) {
  1487.             return($result);
  1488.         }
  1489.         return($this->manager->getSequenceDefinition($this, $sequence));
  1490.     }
  1491.  
  1492.     // }}}
  1493.     // {{{ query()
  1494.  
  1495.     /**
  1496.      * Send a query to the database and return any results
  1497.      *
  1498.      * @param string $query the SQL query
  1499.      * @param mixed   $types  array that contains the types of the columns in
  1500.      *                        the result set
  1501.      * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  1502.      * @access public
  1503.      */
  1504.     function query($query, $types = NULL)
  1505.     {
  1506.         $this->debug("Query: $query");
  1507.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Query: database queries are not implemented'));
  1508.     }
  1509.  
  1510.     // }}}
  1511.     // {{{ setSelectedRowRange()
  1512.  
  1513.     /**
  1514.      * set the range of the next query
  1515.      *
  1516.      * @param string $first first row to select
  1517.      * @param string $limit number of rows to select
  1518.      * @return mixed MDB_OK on success, a MDB error on failure
  1519.      * @access public
  1520.      */
  1521.     function setSelectedRowRange($first, $limit)
  1522.     {
  1523.         if (!isset($this->supported['SelectRowRanges'])) {
  1524.             return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  1525.                 'Set selected row range: selecting row ranges is not supported by this driver'));
  1526.         }
  1527.         $first = (int)$first;
  1528.         if ($first < 0) {
  1529.             return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1530.                 'Set selected row range: it was not specified a valid first selected range row'));
  1531.         }
  1532.         $limit = (int)$limit;
  1533.         if ($limit < 1) {
  1534.             return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1535.                 'Set selected row range: it was not specified a valid selected range row limit'));
  1536.         }
  1537.         $this->first_selected_row = $first;
  1538.         $this->selected_row_limit = $limit;
  1539.         return(MDB_OK);
  1540.     }
  1541.  
  1542.     // }}}
  1543.     // {{{ limitQuery()
  1544.  
  1545.     /**
  1546.      * Generates a limited query
  1547.      *
  1548.      * @param string $query query
  1549.      * @param mixed   $types  array that contains the types of the columns in
  1550.      *                        the result set
  1551.      * @param integer $from the row to start to fetching
  1552.      * @param integer $count the numbers of rows to fetch
  1553.      * @return mixed a valid ressource pointer or a MDB_Error
  1554.      * @access public
  1555.      */
  1556.     function limitQuery($query, $types = NULL, $from, $count)
  1557.     {
  1558.         $result = $this->setSelectedRowRange($from, $count);
  1559.         if (MDB::isError($result)) {
  1560.             return($result);
  1561.         }
  1562.         return($this->query($query, $types));
  1563.     }
  1564.  
  1565.     // }}}
  1566.     // {{{ subSelect()
  1567.  
  1568.     /**
  1569.      * simple subselect emulation: leaves the query untouched for all RDBMS
  1570.      * that support subselects
  1571.      *
  1572.      * @access public
  1573.      *
  1574.      * @param string $query the SQL query for the subselect that may only
  1575.      *                      return a column
  1576.      * @param string $quote determines if the data needs to be quoted before
  1577.      *                      being returned
  1578.      *
  1579.      * @return string the query
  1580.      */
  1581.     function subSelect($query, $quote = FALSE)
  1582.     {
  1583.         if ($this->supported['SubSelects'] == 1) {
  1584.             return($query);
  1585.         }
  1586.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Subselect: subselect not implemented'));
  1587.     }
  1588.  
  1589.     // }}}
  1590.     // {{{ replace()
  1591.  
  1592.     /**
  1593.      * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
  1594.      * query, except that if there is already a row in the table with the same
  1595.      * key field values, the REPLACE query just updates its values instead of
  1596.      * inserting a new row.
  1597.      *
  1598.      * The REPLACE type of query does not make part of the SQL standards. Since
  1599.      * pratically only MySQL implements it natively, this type of query is
  1600.      * emulated through this method for other DBMS using standard types of
  1601.      * queries inside a transaction to assure the atomicity of the operation.
  1602.      *
  1603.      * @param string $table name of the table on which the REPLACE query will
  1604.      *       be executed.
  1605.      * @param array $fields associative array that describes the fields and the
  1606.      *       values that will be inserted or updated in the specified table. The
  1607.      *       indexes of the array are the names of all the fields of the table.
  1608.      *       The values of the array are also associative arrays that describe
  1609.      *       the values and other properties of the table fields.
  1610.      *
  1611.      *       Here follows a list of field properties that need to be specified:
  1612.      *
  1613.      *       Value
  1614.      *           Value to be assigned to the specified field. This value may be
  1615.      *           of specified in database independent type format as this
  1616.      *           function can perform the necessary datatype conversions.
  1617.      *
  1618.      *           Default: this property is required unless the Null property is
  1619.      *           set to 1.
  1620.      *
  1621.      *       Type
  1622.      *           Name of the type of the field. Currently, all types Metabase
  1623.      *           are supported except for clob and blob.
  1624.      *
  1625.      *           Default: no type conversion
  1626.      *
  1627.      *       Null
  1628.      *           Boolean property that indicates that the value for this field
  1629.      *           should be set to NULL.
  1630.      *
  1631.      *           The default value for fields missing in INSERT queries may be
  1632.      *           specified the definition of a table. Often, the default value
  1633.      *           is already NULL, but since the REPLACE may be emulated using
  1634.      *           an UPDATE query, make sure that all fields of the table are
  1635.      *           listed in this function argument array.
  1636.      *
  1637.      *           Default: 0
  1638.      *
  1639.      *       Key
  1640.      *           Boolean property that indicates that this field should be
  1641.      *           handled as a primary key or at least as part of the compound
  1642.      *           unique index of the table that will determine the row that will
  1643.      *           updated if it exists or inserted a new row otherwise.
  1644.      *
  1645.      *           This function will fail if no key field is specified or if the
  1646.      *           value of a key field is set to NULL because fields that are
  1647.      *           part of unique index they may not be NULL.
  1648.      *
  1649.      *           Default: 0
  1650.      * @return mixed MDB_OK on success, a MDB error on failure
  1651.      * @access public
  1652.      */
  1653.     function replace($table, $fields)
  1654.     {
  1655.         if (!$this->supported['Replace']) {
  1656.             return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Replace: replace query is not supported'));
  1657.         }
  1658.         $count = count($fields);
  1659.         for($keys = 0, $condition = $insert = $values = '', reset($fields), $field = 0;
  1660.             $field < $count;
  1661.             next($fields), $field++)
  1662.         {
  1663.             $name = key($fields);
  1664.             if ($field > 0) {
  1665.                 $insert .= ', ';
  1666.                 $values .= ', ';
  1667.             }
  1668.             $insert .= $name;
  1669.             if (isset($fields[$name]['Null']) && $fields[$name]['Null']) {
  1670.                 $value = 'NULL';
  1671.             } else {
  1672.                 if(isset($fields[$name]['Type'])) {
  1673.                     switch ($fields[$name]['Type']) {
  1674.                         case 'text':
  1675.                             $value = $this->getTextValue($fields[$name]['Value']);
  1676.                             break;
  1677.                         case 'boolean':
  1678.                             $value = $this->getBooleanValue($fields[$name]['Value']);
  1679.                             break;
  1680.                         case 'integer':
  1681.                             $value = $this->getIntegerValue($fields[$name]['Value']);
  1682.                             break;
  1683.                         case 'decimal':
  1684.                             $value = $this->getDecimalValue($fields[$name]['Value']);
  1685.                             break;
  1686.                         case 'float':
  1687.                             $value = $this->getFloatValue($fields[$name]['Value']);
  1688.                             break;
  1689.                         case 'date':
  1690.                             $value = $this->getDateValue($fields[$name]['Value']);
  1691.                             break;
  1692.                         case 'time':
  1693.                             $value = $this->getTimeValue($fields[$name]['Value']);
  1694.                             break;
  1695.                         case 'timestamp':
  1696.                             $value = $this->getTimestampValue($fields[$name]['Value']);
  1697.                             break;
  1698.                         default:
  1699.                             return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
  1700.                                 'no supported type for field "' . $name . '" specified'));
  1701.                     }
  1702.                 } else {
  1703.                     $value = $fields[$name]['Value'];
  1704.                 }
  1705.             }
  1706.             $values .= $value;
  1707.             if (isset($fields[$name]['Key']) && $fields[$name]['Key']) {
  1708.                 if ($value === 'NULL') {
  1709.                     return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
  1710.                         'key values may not be NULL'));
  1711.                 }
  1712.                 $condition .= ($keys ? ' AND ' : ' WHERE ') . $name . '=' . $value;
  1713.                 $keys++;
  1714.             }
  1715.         }
  1716.         if ($keys == 0) {
  1717.             return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL,
  1718.                 'not specified which fields are keys'));
  1719.         }
  1720.         $in_transaction = $this->in_transaction;
  1721.         if (!$in_transaction && MDB::isError($result = $this->autoCommit(FALSE))) {
  1722.             return($result);
  1723.         }
  1724.         $success = $this->query("DELETE FROM $table$condition");
  1725.         if (!MDB::isError($success)) {
  1726.             $affected_rows = $this->affected_rows;
  1727.             $success = $this->query("INSERT INTO $table ($insert) VALUES ($values)");
  1728.             $affected_rows += $this->affected_rows;
  1729.         }
  1730.  
  1731.         if (!$in_transaction) {
  1732.             if (!MDB::isError($success)) {
  1733.                 if (!MDB::isError($success = $this->commit())
  1734.                     && !MDB::isError($success = $this->autoCommit(TRUE))
  1735.                     && isset($this->supported['AffectedRows'])
  1736.                 ) {
  1737.                     $this->affected_rows = $affected_rows;
  1738.                 }
  1739.             } else {
  1740.                 $this->rollback();
  1741.                 $this->autoCommit(TRUE);
  1742.             }
  1743.         }
  1744.         return($success);
  1745.     }
  1746.  
  1747.     // }}}
  1748.     // {{{ prepareQuery()
  1749.  
  1750.     /**
  1751.      * Prepares a query for multiple execution with execute().
  1752.      * With some database backends, this is emulated.
  1753.      * prepareQuery() requires a generic query as string like
  1754.      * 'INSERT INTO numbers VALUES(?,?,?)'. The ? are wildcards.
  1755.      * Types of wildcards:
  1756.      *    ? - a quoted scalar value, i.e. strings, integers
  1757.      *
  1758.      * @param string $ the query to prepare
  1759.      * @return mixed resource handle for the prepared query on success, a DB
  1760.      *        error on failure
  1761.      * @access public
  1762.      * @see execute
  1763.      */
  1764.     function prepareQuery($query)
  1765.     {
  1766.         $this->debug("PrepareQuery: $query");
  1767.         $positions = array();
  1768.         for($position = 0;
  1769.             $position < strlen($query) && is_integer($question = strpos($query, '?', $position));
  1770.         ) {
  1771.             if (is_integer($quote = strpos($query, "'", $position))
  1772.                 && $quote < $question
  1773.             ) {
  1774.                 if (!is_integer($end_quote = strpos($query, "'", $quote + 1))) {
  1775.                     return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  1776.                         'Prepare query: query with an unterminated text string specified'));
  1777.                 }
  1778.                 switch ($this->escape_quotes) {
  1779.                     case '':
  1780.                     case "'":
  1781.                         $position = $end_quote + 1;
  1782.                         break;
  1783.                     default:
  1784.                         if ($end_quote == $quote + 1) {
  1785.                             $position = $end_quote + 1;
  1786.                         } else {
  1787.                             if ($query[$end_quote-1] == $this->escape_quotes) {
  1788.                                 $position = $end_quote;
  1789.                             } else {
  1790.                                 $position = $end_quote + 1;
  1791.                             }
  1792.                         }
  1793.                         break;
  1794.                 }
  1795.             } else {
  1796.                 $positions[] = $question;
  1797.                 $position = $question + 1;
  1798.             }
  1799.         }
  1800.         $this->prepared_queries[] = array(
  1801.             'Query' => $query,
  1802.             'Positions' => $positions,
  1803.             'Values' => array(),
  1804.             'Types' => array()
  1805.             );
  1806.         $prepared_query = count($this->prepared_queries);
  1807.         if ($this->selected_row_limit > 0) {
  1808.             $this->prepared_queries[$prepared_query-1]['First'] = $this->first_selected_row;
  1809.             $this->prepared_queries[$prepared_query-1]['Limit'] = $this->selected_row_limit;
  1810.         }
  1811.         return($prepared_query);
  1812.     }
  1813.  
  1814.     // }}}
  1815.     // {{{ _validatePreparedQuery()
  1816.  
  1817.     /**
  1818.      * validate that a handle is infact a prepared query
  1819.      *
  1820.      * @param int $prepared_query argument is a handle that was returned by
  1821.      *       the function prepareQuery()
  1822.      * @access private
  1823.      */
  1824.     function _validatePreparedQuery($prepared_query)
  1825.     {
  1826.         if ($prepared_query < 1 || $prepared_query > count($this->prepared_queries)) {
  1827.             return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  1828.                 'Validate prepared query: invalid prepared query'));
  1829.         }
  1830.         if (gettype($this->prepared_queries[$prepared_query-1]) != 'array') {
  1831.             return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  1832.                 'Validate prepared query: prepared query was already freed'));
  1833.         }
  1834.         return(MDB_OK);
  1835.     }
  1836.  
  1837.     // }}}
  1838.     // {{{ freePreparedQuery()
  1839.  
  1840.     /**
  1841.      * Release resources allocated for the specified prepared query.
  1842.      *
  1843.      * @param int $prepared_query argument is a handle that was returned by
  1844.      *       the function prepareQuery()
  1845.      * @return mixed MDB_OK on success, a MDB error on failure
  1846.      * @access public
  1847.      */
  1848.     function freePreparedQuery($prepared_query)
  1849.     {
  1850.         $result = $this->_validatePreparedQuery($prepared_query);
  1851.         if (MDB::isError($result)) {
  1852.             return($result);
  1853.         }
  1854.         $this->prepared_queries[$prepared_query-1] = '';
  1855.         return(MDB_OK);
  1856.     }
  1857.  
  1858.     // }}}
  1859.     // {{{ _executePreparedQuery()
  1860.  
  1861.     /**
  1862.      * Execute a prepared query statement.
  1863.      *
  1864.      * @param int $prepared_query argument is a handle that was returned by
  1865.      *       the function prepareQuery()
  1866.      * @param string $query query to be executed
  1867.      * @param array $types array that contains the types of the columns in
  1868.      *       the result set
  1869.      * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  1870.      * @access private
  1871.      */
  1872.     function _executePreparedQuery($prepared_query, $query, $types = NULL)
  1873.     {
  1874.         return($this->query($query, $types));
  1875.     }
  1876.  
  1877.     // }}}
  1878.     // {{{ executeQuery()
  1879.  
  1880.     /**
  1881.      * Execute a prepared query statement.
  1882.      *
  1883.      * @param int $prepared_query argument is a handle that was returned by
  1884.      *       the function prepareQuery()
  1885.      * @param array $types array that contains the types of the columns in the
  1886.      *       result set
  1887.      * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  1888.      * @access public
  1889.      */
  1890.     function executeQuery($prepared_query, $types = NULL)
  1891.     {
  1892.         $result = $this->_validatePreparedQuery($prepared_query);
  1893.         if (MDB::isError($result)) {
  1894.             return($result);
  1895.         }
  1896.         $index = $prepared_query-1;
  1897.         $success = MDB_OK;
  1898.         $this->clobs[$prepared_query] = $this->blobs[$prepared_query] = array();
  1899.         $query = '';
  1900.         for($last_position = $position = 0;
  1901.             $position < count($this->prepared_queries[$index]['Positions']);
  1902.             $position++) {
  1903.             if (!isset($this->prepared_queries[$index]['Values'][$position])) {
  1904.                 return($this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
  1905.                     'Execute query: it was not defined query argument '.($position + 1)));
  1906.             }
  1907.             $current_position = $this->prepared_queries[$index]['Positions'][$position];
  1908.             $query .= substr($this->prepared_queries[$index]['Query'], $last_position, $current_position - $last_position);
  1909.             $value = $this->prepared_queries[$index]['Values'][$position];
  1910.             if ($this->prepared_queries[$index]['IsNULL'][$position]) {
  1911.                 $query .= $value;
  1912.             } else {
  1913.                 switch ($this->prepared_queries[$index]['Types'][$position]) {
  1914.                     case 'clob':
  1915.                         if (!MDB::isError($success = $this->getClobValue($prepared_query, $position + 1, $value))) {
  1916.                             $this->clobs[$prepared_query][$position + 1] = $success;
  1917.                             $query .= $this->clobs[$prepared_query][$position + 1];
  1918.                         }
  1919.                         break;
  1920.                     case 'blob':
  1921.                         if (!MDB::isError($success = $this->getBlobValue($prepared_query, $position + 1, $value))) {
  1922.                             $this->blobs[$prepared_query][$position + 1] = $success;
  1923.                             $query .= $this->blobs[$prepared_query][$position + 1];
  1924.                         }
  1925.                         break;
  1926.                     default:
  1927.                         $query .= $value;
  1928.                         break;
  1929.                 }
  1930.             }
  1931.             $last_position = $current_position + 1;
  1932.         }
  1933.         if (!MDB::isError($success)) {
  1934.             $query .= substr($this->prepared_queries[$index]['Query'], $last_position);
  1935.             if ($this->selected_row_limit > 0) {
  1936.                 $this->prepared_queries[$index]['First'] = $this->first_selected_row;
  1937.                 $this->prepared_queries[$index]['Limit'] = $this->selected_row_limit;
  1938.             }
  1939.             if (isset($this->prepared_queries[$index]['Limit'])
  1940.                 && $this->prepared_queries[$index]['Limit'] > 0
  1941.             ) {
  1942.                 $this->first_selected_row = $this->prepared_queries[$index]['First'];
  1943.                 $this->selected_row_limit = $this->prepared_queries[$index]['Limit'];
  1944.             } else {
  1945.                 $this->first_selected_row = $this->selected_row_limit = 0;
  1946.             }
  1947.             $success = $this->_executePreparedQuery($prepared_query, $query, $types);
  1948.         }
  1949.         for(reset($this->clobs[$prepared_query]), $clob = 0;
  1950.             $clob < count($this->clobs[$prepared_query]);
  1951.             $clob++, next($this->clobs[$prepared_query])) {
  1952.             $this->freeClobValue($prepared_query, key($this->clobs[$prepared_query]), $this->clobs[$prepared_query][key($this->clobs[$prepared_query])], $success);
  1953.         }
  1954.         unset($this->clobs[$prepared_query]);
  1955.         for(reset($this->blobs[$prepared_query]), $blob = 0;
  1956.             $blob < count($this->blobs[$prepared_query]);
  1957.             $blob++, next($this->blobs[$prepared_query])) {
  1958.             $this->freeBlobValue($prepared_query, key($this->blobs[$prepared_query]), $this->blobs[$prepared_query][key($this->blobs[$prepared_query])], $success);
  1959.         }
  1960.         unset($this->blobs[$prepared_query]);
  1961.         return($success);
  1962.     }
  1963.  
  1964.     // }}}
  1965.     // {{{ execute()
  1966.  
  1967.     /**
  1968.      * Executes a prepared SQL query
  1969.      * With execute() the generic query of prepare is assigned with the given
  1970.      * data array. The values of the array inserted into the query in the same
  1971.      * order like the array order
  1972.      *
  1973.      * @param resource $prepared_query query handle from prepare()
  1974.      * @param array $types array that contains the types of the columns in
  1975.      *        the result set
  1976.      * @param array $params numeric array containing the data to insert into
  1977.      *        the query
  1978.      * @param array $param_types array that contains the types of the values
  1979.      *        defined in $params
  1980.      * @return mixed a new result handle or a MDB_Error when fail
  1981.      * @access public
  1982.      * @see prepare()
  1983.      */
  1984.     function execute($prepared_query, $types = NULL, $params = FALSE, $param_types = NULL)
  1985.     {
  1986.         $this->setParamArray($prepared_query, $params, $param_types);
  1987.  
  1988.         return($this->executeQuery($prepared_query, $types));
  1989.     }
  1990.  
  1991.     // }}}
  1992.     // {{{ executeMultiple()
  1993.  
  1994.     /**
  1995.      * This function does several execute() calls on the same statement handle.
  1996.      * $params must be an array indexed numerically from 0, one execute call is
  1997.      * done for every 'row' in the array.
  1998.      *
  1999.      * If an error occurs during execute(), executeMultiple() does not execute
  2000.      * the unfinished rows, but rather returns that error.
  2001.      *
  2002.      * @param resource $stmt query handle from prepare()
  2003.      * @param array $types array that contains the types of the columns in
  2004.      *        the result set
  2005.      * @param array $params numeric array containing the
  2006.      *        data to insert into the query
  2007.      * @param array $parAM_types array that contains the types of the values
  2008.      *        defined in $params
  2009.      * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  2010.      * @access public
  2011.      * @see prepare(), execute()
  2012.      */
  2013.     function executeMultiple($prepared_query, $types = NULL, $params, $param_types = NULL)
  2014.     {
  2015.         for($i = 0, $j = count($params); $i < $j; $i++) {
  2016.             $result = $this->execute($prepared_query, $types, $params[$i], $param_types);
  2017.             if (MDB::isError($result)) {
  2018.                 return($result);
  2019.             }
  2020.         }
  2021.         return(MDB_OK);
  2022.     }
  2023.  
  2024.     // }}}
  2025.     // {{{ setParam()
  2026.  
  2027.     /**
  2028.      * Set the value of a parameter of a prepared query.
  2029.      *
  2030.      * @param int $prepared_query argument is a handle that was returned
  2031.      *       by the function prepareQuery()
  2032.      * @param int $parameter the order number of the parameter in the query
  2033.      *       statement. The order number of the first parameter is 1.
  2034.      * @param string $type designation of the type of the parameter to be set.
  2035.      *       The designation of the currently supported types is as follows:
  2036.      *           text, boolean, integer, decimal, float, date, time, timestamp,
  2037.      *           clob, blob
  2038.      * @param mixed $value value that is meant to be assigned to specified
  2039.      *       parameter. The type of the value depends on the $type argument.
  2040.      * @param boolean $is_null flag that indicates whether whether the
  2041.      *       parameter is a NULL
  2042.      * @param string $field name of the field that is meant to be assigned
  2043.      *       with this parameter value when it is of type clob or blob
  2044.      * @return mixed MDB_OK on success, a MDB error on failure
  2045.      * @access public
  2046.      */
  2047.     function setParam($prepared_query, $parameter, $type, $value, $is_null = 0, $field = '')
  2048.     {
  2049.         $result = $this->_validatePreparedQuery($prepared_query);
  2050.         if (MDB::isError($result)) {
  2051.             return($result);
  2052.         }
  2053.         $index = $prepared_query - 1;
  2054.         if ($parameter < 1 || $parameter > count($this->prepared_queries[$index]['Positions'])) {
  2055.             return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  2056.                 'Query set: it was not specified a valid argument number'));
  2057.         }
  2058.         $this->prepared_queries[$index]['Values'][$parameter-1] = $value;
  2059.         $this->prepared_queries[$index]['Types'][$parameter-1] = $type;
  2060.         $this->prepared_queries[$index]['Fields'][$parameter-1] = $field;
  2061.         $this->prepared_queries[$index]['IsNULL'][$parameter-1] = $is_null;
  2062.         return(MDB_OK);
  2063.     }
  2064.  
  2065.     // }}}
  2066.     // {{{ setParamArray()
  2067.  
  2068.     /**
  2069.      * Set the values of multiple a parameter of a prepared query in bulk.
  2070.      *
  2071.      * @param int $prepared_query argument is a handle that was returned by
  2072.      *       the function prepareQuery()
  2073.      * @param array $params array thats specifies all necessary infromation
  2074.      *       for setParam() the array elements must use keys corresponding to
  2075.      *       the number of the position of the parameter.
  2076.      * @param array $types array thats specifies the types of the fields
  2077.      * @return mixed MDB_OK on success, a MDB error on failure
  2078.      * @access public
  2079.      * @see setParam()
  2080.      */
  2081.     function setParamArray($prepared_query, $params, $types = NULL)
  2082.     {
  2083.         if (is_array($types)) {
  2084.             if (count($params) != count($types)) {
  2085.                 return $this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  2086.                     'setParamArray: the number of given types ('.count($types).')'
  2087.                     .'is not corresponding to the number of given parameters ('.count($params).')');
  2088.             }
  2089.             for($i = 0, $j = count($params); $i < $j; ++$i) {
  2090.                 switch ($types[$i]) {
  2091.                     case 'NULL':
  2092.                         $success = $this->setParam($prepared_query, $i + 1, $params[$i][0], 'NULL', 1, '');
  2093.                         break;
  2094.                     case 'text':
  2095.                         $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
  2096.                         break;
  2097.                     case 'clob':
  2098.                         $success = $this->setParam($prepared_query, $i + 1, 'clob', $params[$i][0], 0, $params[$i][1]);
  2099.                         break;
  2100.                     case 'blob':
  2101.                         $success = $this->setParam($prepared_query, $i + 1, 'blob', $params[$i][0], 0, $params[$i][1]);
  2102.                         break;
  2103.                     case 'integer':
  2104.                         $success = $this->setParam($prepared_query, $i + 1, 'integer', $this->getIntegerValue($params[$i]));
  2105.                         break;
  2106.                     case 'boolean':
  2107.                         $success = $this->setParam($prepared_query, $i + 1, 'boolean', $this->getBooleanValue($params[$i]));
  2108.                         break;
  2109.                     case 'date':
  2110.                         $success = $this->setParam($prepared_query, $i + 1, 'date', $this->getDateValue($params[$i]));
  2111.                         break;
  2112.                     case 'timestamp':
  2113.                         $success = $this->setParam($prepared_query, $i + 1, 'timestamp', $this->getTimestampValue($params[$i]));
  2114.                         break;
  2115.                     case 'time':
  2116.                         $success = $this->setParam($prepared_query, $i + 1, 'time', $this->getTimeValue($params[$i]));
  2117.                         break;
  2118.                     case 'float':
  2119.                         $success = $this->setParam($prepared_query, $i + 1, 'float', $this->getFloatValue($params[$i]));
  2120.                         break;
  2121.                     case 'decimal':
  2122.                         $success = $this->setParam($prepared_query, $i + 1, 'decimal', $this->getDecimalValue($params[$i]));
  2123.                         break;
  2124.                     default:
  2125.                         $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
  2126.                         break;
  2127.                 }
  2128.                 if (MDB::isError($success)) {
  2129.                     return($success);
  2130.                 }
  2131.             }
  2132.         } else {
  2133.             for($i = 0, $j = count($params); $i < $j; ++$i) {
  2134.                 $success = $this->setParam($prepared_query, $i + 1, 'text', $this->getTextValue($params[$i]));
  2135.                 if (MDB::isError($success)) {
  2136.                     return($success);
  2137.                 }
  2138.             }
  2139.         }
  2140.         return(MDB_OK);
  2141.     }
  2142.  
  2143.     // }}}
  2144.     // {{{ setParamNull()
  2145.  
  2146.     /**
  2147.      * Set the value of a parameter of a prepared query to NULL.
  2148.      *
  2149.      * @param int $prepared_query argument is a handle that was returned by
  2150.      *       the function prepareQuery()
  2151.      * @param int $parameter order number of the parameter in the query
  2152.      *       statement. The order number of the first parameter is 1.
  2153.      * @param string $type designation of the type of the parameter to be set.
  2154.      *       The designation of the currently supported types is list in the
  2155.      *       usage of the function  setParam()
  2156.      * @return mixed MDB_OK on success, a MDB error on failure
  2157.      * @access public
  2158.      * @see setParam()
  2159.      */
  2160.     function setParamNull($prepared_query, $parameter, $type)
  2161.     {
  2162.         return($this->setParam($prepared_query, $parameter, $type, 'NULL', 1, ''));
  2163.     }
  2164.  
  2165.     // }}}
  2166.     // {{{ setParamText()
  2167.  
  2168.     /**
  2169.      * Set a parameter of a prepared query with a text value.
  2170.      *
  2171.      * @param int $prepared_query argument is a handle that was returned by
  2172.      *       the function prepareQuery()
  2173.      * @param int $parameter order number of the parameter in the query
  2174.      *       statement. The order number of the first parameter is 1.
  2175.      * @param string $value text value that is meant to be assigned to
  2176.      *       specified parameter.
  2177.      * @return mixed MDB_OK on success, a MDB error on failure
  2178.      * @access public
  2179.      * @see setParam()
  2180.      */
  2181.     function setParamText($prepared_query, $parameter, $value)
  2182.     {
  2183.         return($this->setParam($prepared_query, $parameter, 'text', $this->getTextValue($value)));
  2184.     }
  2185.  
  2186.     // }}}
  2187.     // {{{ setParamClob()
  2188.  
  2189.     /**
  2190.      * Set a parameter of a prepared query with a character large object value.
  2191.      *
  2192.      * @param int $prepared_query argument is a handle that was returned by
  2193.      *       the function prepareQuery()
  2194.      * @param int $parameter order number of the parameter in the query
  2195.      *       statement. The order number of the first parameter is 1.
  2196.      * @param int $value handle of large object created with createLOB()
  2197.      *       function from which it will be read the data value that is meant
  2198.      *       to be assigned to specified parameter.
  2199.      * @param string $field name of the field of a INSERT or UPDATE query to
  2200.      *       which it will be assigned the value to specified parameter.
  2201.      * @return mixed MDB_OK on success, a MDB error on failure
  2202.      * @access public
  2203.      * @see setParam()
  2204.      */
  2205.     function setParamClob($prepared_query, $parameter, $value, $field)
  2206.     {
  2207.         return($this->setParam($prepared_query, $parameter, 'clob', $value, 0, $field));
  2208.     }
  2209.  
  2210.     // }}}
  2211.     // {{{ setParamBlob()
  2212.  
  2213.     /**
  2214.      * Set a parameter of a prepared query with a binary large object value.
  2215.      *
  2216.      * @param int $prepared_query argument is a handle that was returned by
  2217.      *       the function prepareQuery()
  2218.      * @param int $parameter order number of the parameter in the query
  2219.      *       statement. The order number of the first parameter is 1.
  2220.      * @param int $value handle of large object created with createLOB()
  2221.      *       function from which it will be read the data value that is meant
  2222.      *       to be assigned to specified parameter.
  2223.      * @param string $field name of the field of a INSERT or UPDATE query to
  2224.      *       which it will be assigned the value to specified parameter.
  2225.      * @return mixed MDB_OK on success, a MDB error on failure
  2226.      * @access public
  2227.      * @see setParam()
  2228.      */
  2229.     function setParamBlob($prepared_query, $parameter, $value, $field)
  2230.     {
  2231.         return($this->setParam($prepared_query, $parameter, 'blob', $value, 0, $field));
  2232.     }
  2233.  
  2234.     // }}}
  2235.     // {{{ setParamInteger()
  2236.  
  2237.     /**
  2238.      * Set a parameter of a prepared query with a text value.
  2239.      *
  2240.      * @param int $prepared_query argument is a handle that was returned by
  2241.      *       the function prepareQuery()
  2242.      * @param int $parameter order number of the parameter in the query
  2243.      *       statement. The order number of the first parameter is 1.
  2244.      * @param int $value an integer value that is meant to be assigned to
  2245.      *       specified parameter.
  2246.      * @return mixed MDB_OK on success, a MDB error on failure
  2247.      * @access public
  2248.      * @see setParam()
  2249.      */
  2250.     function setParamInteger($prepared_query, $parameter, $value)
  2251.     {
  2252.         return($this->setParam($prepared_query, $parameter, 'integer', $this->getIntegerValue($value)));
  2253.     }
  2254.  
  2255.     // }}}
  2256.     // {{{ setParamBoolean()
  2257.  
  2258.     /**
  2259.      * Set a parameter of a prepared query with a boolean value.
  2260.      *
  2261.      * @param int $prepared_query argument is a handle that was returned by
  2262.      *       the function prepareQuery()
  2263.      * @param int $parameter order number of the parameter in the query
  2264.      *       statement. The order number of the first parameter is 1.
  2265.      * @param boolean $value boolean value that is meant to be assigned to
  2266.      *       specified parameter.
  2267.      * @return mixed MDB_OK on success, a MDB error on failure
  2268.      * @access public
  2269.      * @see setParam()
  2270.      */
  2271.     function setParamBoolean($prepared_query, $parameter, $value)
  2272.     {
  2273.         return($this->setParam($prepared_query, $parameter, 'boolean', $this->getBooleanValue($value)));
  2274.     }
  2275.  
  2276.     // }}}
  2277.     // {{{ setParamDate()
  2278.  
  2279.     /**
  2280.      * Set a parameter of a prepared query with a date value.
  2281.      *
  2282.      * @param int $prepared_query argument is a handle that was returned by
  2283.      *       the function prepareQuery()
  2284.      * @param int $parameter order number of the parameter in the query
  2285.      *       statement. The order number of the first parameter is 1.
  2286.      * @param string $value date value that is meant to be assigned to
  2287.      *       specified parameter.
  2288.      * @return mixed MDB_OK on success, a MDB error on failure
  2289.      * @access public
  2290.      * @see setParam()
  2291.      */
  2292.     function setParamDate($prepared_query, $parameter, $value)
  2293.     {
  2294.         return($this->setParam($prepared_query, $parameter, 'date', $this->getDateValue($value)));
  2295.     }
  2296.  
  2297.     // }}}
  2298.     // {{{ setParamTimestamp()
  2299.  
  2300.     /**
  2301.      * Set a parameter of a prepared query with a time stamp value.
  2302.      *
  2303.      * @param int $prepared_query argument is a handle that was returned by
  2304.      *       the function prepareQuery()
  2305.      * @param int $parameter order number of the parameter in the query
  2306.      *       statement. The order number of the first parameter is 1.
  2307.      * @param string $value time stamp value that is meant to be assigned to
  2308.      *       specified parameter.
  2309.      * @return mixed MDB_OK on success, a MDB error on failure
  2310.      * @access public
  2311.      * @see setParam()
  2312.      */
  2313.     function setParamTimestamp($prepared_query, $parameter, $value)
  2314.     {
  2315.         return($this->setParam($prepared_query, $parameter, 'timestamp', $this->getTimestampValue($value)));
  2316.     }
  2317.  
  2318.     // }}}
  2319.     // {{{ setParamTime()
  2320.  
  2321.     /**
  2322.      * Set a parameter of a prepared query with a time value.
  2323.      *
  2324.      * @param int $prepared_query argument is a handle that was returned by
  2325.      *       the function prepareQuery()
  2326.      * @param int $parameter order number of the parameter in the query
  2327.      *       statement. The order number of the first parameter is 1.
  2328.      * @param string $value time value that is meant to be assigned to
  2329.      *       specified parameter.
  2330.      * @return mixed MDB_OK on success, a MDB error on failure
  2331.      * @access public
  2332.      * @see setParam()
  2333.      */
  2334.     function setParamTime($prepared_query, $parameter, $value)
  2335.     {
  2336.         return($this->setParam($prepared_query, $parameter, 'time', $this->getTimeValue($value)));
  2337.     }
  2338.  
  2339.     // }}}
  2340.     // {{{ setParamFloat()
  2341.  
  2342.     /**
  2343.      * Set a parameter of a prepared query with a float value.
  2344.      *
  2345.      * @param int $prepared_query argument is a handle that was returned by
  2346.      *       the function prepareQuery()
  2347.      * @param int $parameter order number of the parameter in the query
  2348.      *       statement. The order number of the first parameter is 1.
  2349.      * @param string $value float value that is meant to be assigned to
  2350.      *       specified parameter.
  2351.      * @return mixed MDB_OK on success, a MDB error on failure
  2352.      * @access public
  2353.      * @see setParam()
  2354.      */
  2355.     function setParamFloat($prepared_query, $parameter, $value)
  2356.     {
  2357.         return($this->setParam($prepared_query, $parameter, 'float', $this->getFloatValue($value)));
  2358.     }
  2359.  
  2360.     // }}}
  2361.     // {{{ setParamDecimal()
  2362.  
  2363.     /**
  2364.      * Set a parameter of a prepared query with a decimal value.
  2365.      *
  2366.      * @param int $prepared_query argument is a handle that was returned by
  2367.      *       the function prepareQuery()
  2368.      * @param int $parameter order number of the parameter in the query
  2369.      *       statement. The order number of the first parameter is 1.
  2370.      * @param string $value decimal value that is meant to be assigned to
  2371.      *       specified parameter.
  2372.      * @return mixed MDB_OK on success, a MDB error on failure
  2373.      * @access public
  2374.      * @see setParam()
  2375.      */
  2376.     function setParamDecimal($prepared_query, $parameter, $value)
  2377.     {
  2378.         return($this->setParam($prepared_query, $parameter, 'decimal', $this->getDecimalValue($value)));
  2379.     }
  2380.  
  2381.     // }}}
  2382.     // {{{ setResultTypes()
  2383.  
  2384.     /**
  2385.      * Define the list of types to be associated with the columns of a given
  2386.      * result set.
  2387.      *
  2388.      * This function may be called before invoking fetchInto(), fetchOne(),
  2389.      * fetchRow(), fetchCol() and fetchAll() so that the necessary data type
  2390.      * conversions are performed on the data to be retrieved by them. If this
  2391.      * function is not called, the type of all result set columns is assumed
  2392.      * to be text, thus leading to not perform any conversions.
  2393.      *
  2394.      * @param resource $result result identifier
  2395.      * @param string $types array variable that lists the
  2396.      *       data types to be expected in the result set columns. If this array
  2397.      *       contains less types than the number of columns that are returned
  2398.      *       in the result set, the remaining columns are assumed to be of the
  2399.      *       type text. Currently, the types clob and blob are not fully
  2400.      *       supported.
  2401.      * @return mixed MDB_OK on success, a MDB error on failure
  2402.      * @access public
  2403.      */
  2404.     function setResultTypes($result, $types)
  2405.     {
  2406.         if (isset($this->result_types[$result])) {
  2407.             return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  2408.                 'Set result types: attempted to redefine the types of the columns of a result set'));
  2409.         }
  2410.         $columns = $this->numCols($result);
  2411.         if (MDB::isError($columns)) {
  2412.             return($columns);
  2413.         }
  2414.         if ($columns < count($types)) {
  2415.             return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  2416.                 'Set result types: it were specified more result types (' . count($types) . ') than result columns (' . $columns . ')'));
  2417.         }
  2418.         $valid_types = array(
  2419.             'text'      => MDB_TYPE_TEXT,
  2420.             'boolean'   => MDB_TYPE_BOOLEAN,
  2421.             'integer'   => MDB_TYPE_INTEGER,
  2422.             'decimal'   => MDB_TYPE_DECIMAL,
  2423.             'float'     => MDB_TYPE_FLOAT,
  2424.             'date'      => MDB_TYPE_DATE,
  2425.             'time'      => MDB_TYPE_TIME,
  2426.             'timestamp' => MDB_TYPE_TIMESTAMP,
  2427.             'clob'      => MDB_TYPE_CLOB,
  2428.             'blob'      => MDB_TYPE_BLOB
  2429.         );
  2430.         for($column = 0; $column < count($types); $column++) {
  2431.             if (!isset($valid_types[$types[$column]])) {
  2432.                 return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2433.                     'Set result types: ' . $types[$column] . ' is not a supported column type'));
  2434.             }
  2435.             $this->result_types[$result][$column] = $valid_types[$types[$column]];
  2436.         }
  2437.         while ($column < $columns) {
  2438.             $this->result_types[$result][$column] = MDB_TYPE_TEXT;
  2439.             $column++;
  2440.         }
  2441.         return(MDB_OK);
  2442.     }
  2443.  
  2444.     // }}}
  2445.     // {{{ affectedRows()
  2446.  
  2447.     /**
  2448.      * returns the affected rows of a query
  2449.      *
  2450.      * @return mixed MDB_Error or number of rows
  2451.      * @access public
  2452.      */
  2453.     function affectedRows()
  2454.     {
  2455.         if ($this->affected_rows == -1) {
  2456.             return($this->raiseError(MDB_ERROR_NEED_MORE_DATA));
  2457.         }
  2458.         return($this->affected_rows);
  2459.     }
  2460.  
  2461.     // }}}
  2462.     // {{{ getColumnNames()
  2463.  
  2464.     /**
  2465.      * Retrieve the names of columns returned by the DBMS in a query result.
  2466.      *
  2467.      * @param resource $result result identifier
  2468.      * @return mixed associative array variable
  2469.      *       that holds the names of columns. The indexes of the array are
  2470.      *       the column names mapped to lower case and the values are the
  2471.      *       respective numbers of the columns starting from 0. Some DBMS may
  2472.      *       not return any columns when the result set does not contain any
  2473.      *       rows.
  2474.      *      a MDB error on failure
  2475.      * @access public
  2476.      */
  2477.     function getColumnNames($result)
  2478.     {
  2479.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2480.             'Get column names: obtaining result column names is not implemented'));
  2481.     }
  2482.  
  2483.     // }}}
  2484.     // {{{ numCols()
  2485.  
  2486.     /**
  2487.      * Count the number of columns returned by the DBMS in a query result.
  2488.      *
  2489.      * @param resource $result result identifier
  2490.      * @return mixed integer value with the number of columns, a MDB error
  2491.      *       on failure
  2492.      * @access public
  2493.      */
  2494.     function numCols($result)
  2495.     {
  2496.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2497.             'Number of columns: obtaining the number of result columns is not implemented'));
  2498.     }
  2499.  
  2500.     // }}}
  2501.     // {{{ endOfResult()
  2502.  
  2503.     /**
  2504.      * check if the end of the result set has been reached
  2505.      *
  2506.      * @param resource $result result identifier
  2507.      * @return mixed TRUE or FALSE on sucess, a MDB error on failure
  2508.      * @access public
  2509.      */
  2510.     function endOfResult($result)
  2511.     {
  2512.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2513.             'End of result: end of result method not implemented'));
  2514.     }
  2515.  
  2516.     // }}}
  2517.     // {{{ setFetchMode()
  2518.  
  2519.     /**
  2520.      * Sets which fetch mode should be used by default on queries
  2521.      * on this connection.
  2522.      *
  2523.      * @param integer $fetchmode MDB_FETCHMODE_ORDERED or MDB_FETCHMODE_ASSOC,
  2524.      *       possibly bit-wise OR'ed with MDB_FETCHMODE_FLIPPED.
  2525.      * @access public
  2526.      * @see MDB_FETCHMODE_ORDERED
  2527.      * @see MDB_FETCHMODE_ASSOC
  2528.      * @see MDB_FETCHMODE_FLIPPED
  2529.      */
  2530.     function setFetchMode($fetchmode)
  2531.     {
  2532.         switch ($fetchmode) {
  2533.             case MDB_FETCHMODE_ORDERED:
  2534.             case MDB_FETCHMODE_ASSOC:
  2535.                 $this->fetchmode = $fetchmode;
  2536.                 break;
  2537.             default:
  2538.                 return($this->raiseError('invalid fetchmode mode'));
  2539.         }
  2540.     }
  2541.  
  2542.     // }}}
  2543.     // {{{ fetch()
  2544.  
  2545.     /**
  2546.      * fetch value from a result set
  2547.      *
  2548.      * @param resource $result result identifier
  2549.      * @param int $row number of the row where the data can be found
  2550.      * @param int $field field number where the data can be found
  2551.      * @return mixed string on success, a MDB error on failure
  2552.      * @access public
  2553.      */
  2554.     function fetch($result, $row, $field)
  2555.     {
  2556.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2557.             'Fetch: fetch result method not implemented'));
  2558.     }
  2559.  
  2560.     // }}}
  2561.     // {{{ fetchLob()
  2562.  
  2563.     /**
  2564.      * fetch a lob value from a result set
  2565.      *
  2566.      * @param resource $result result identifier
  2567.      * @param int $row number of the row where the data can be found
  2568.      * @param int $field field number where the data can be found
  2569.      * @return mixed string on success, a MDB error on failure
  2570.      * @access public
  2571.      */
  2572.     function fetchLob($result, $row, $field)
  2573.     {
  2574.         $lob = count($this->lobs) + 1;
  2575.         $this->lobs[$lob] = array(
  2576.             'Result' => $result,
  2577.             'Row' => $row,
  2578.             'Field' => $field,
  2579.             'Position' => 0
  2580.         );
  2581.         $dst_lob = array(
  2582.             'Database' => $this,
  2583.             'Error' => '',
  2584.             'Type' => 'resultlob',
  2585.             'ResultLOB' => $lob
  2586.         );
  2587.         if (MDB::isError($lob = $this->createLob($dst_lob))) {
  2588.             return($this->raiseError(MDB_ERROR, NULL, NULL,
  2589.                 'Fetch LOB result: ' . $dst_lob['Error']));
  2590.         }
  2591.         return($lob);
  2592.     }
  2593.  
  2594.     // }}}
  2595.     // {{{ _retrieveLob()
  2596.  
  2597.     /**
  2598.      * fetch a float value from a result set
  2599.      *
  2600.      * @param int $lob handle to a lob created by the createLob() function
  2601.      * @return mixed MDB_OK on success, a MDB error on failure
  2602.      * @access private
  2603.      */
  2604.     function _retrieveLob($lob)
  2605.     {
  2606.         if (!isset($this->lobs[$lob])) {
  2607.             return($this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
  2608.                 'Fetch LOB result: it was not specified a valid lob'));
  2609.         }
  2610.         if (!isset($this->lobs[$lob]['Value'])) {
  2611.             $this->lobs[$lob]['Value'] = $this->fetch($this->lobs[$lob]['Result'], $this->lobs[$lob]['Row'], $this->lobs[$lob]['Field']);
  2612.         }
  2613.         return(MDB_OK);
  2614.     }
  2615.  
  2616.     // }}}
  2617.     // {{{ endOfResultLob()
  2618.  
  2619.     /**
  2620.      * Determine whether it was reached the end of the large object and
  2621.      * therefore there is no more data to be read for the its input stream.
  2622.      *
  2623.      * @param int $lob handle to a lob created by the createLob() function
  2624.      * @return mixed TRUE or FALSE on success, a MDB error on failure
  2625.      * @access public
  2626.      */
  2627.     function endOfResultLob($lob)
  2628.     {
  2629.         $result = $this->_retrieveLob($lob);
  2630.         if (MDB::isError($result)) {
  2631.             return($result);
  2632.         }
  2633.         return($this->lobs[$lob]['Position'] >= strlen($this->lobs[$lob]['Value']));
  2634.     }
  2635.  
  2636.     // }}}
  2637.     // {{{ _readResultLob()
  2638.  
  2639.     /**
  2640.      * Read data from large object input stream.
  2641.      *
  2642.      * @param int $lob handle to a lob created by the createLob() function
  2643.      * @param blob $data reference to a variable that will hold data to be
  2644.      *       read from the large object input stream
  2645.      * @param int $length integer value that indicates the largest ammount of
  2646.      *       data to be read from the large object input stream.
  2647.      * @return mixed length on success, a MDB error on failure
  2648.      * @access private
  2649.      */
  2650.     function _readResultLob($lob, &$data, $length)
  2651.     {
  2652.         $result = $this->_retrieveLob($lob);
  2653.         if (MDB::isError($result)) {
  2654.             return($result);
  2655.         }
  2656.         $length = min($length, strlen($this->lobs[$lob]['Value']) - $this->lobs[$lob]['Position']);
  2657.         $data = substr($this->lobs[$lob]['Value'], $this->lobs[$lob]['Position'], $length);
  2658.         $this->lobs[$lob]['Position'] += $length;
  2659.         return($length);
  2660.     }
  2661.  
  2662.     // }}}
  2663.     // {{{ _destroyResultLob()
  2664.  
  2665.     /**
  2666.      * Free any resources allocated during the lifetime of the large object
  2667.      * handler object.
  2668.      *
  2669.      * @param int $lob handle to a lob created by the createLob() function
  2670.      * @access private
  2671.      */
  2672.     function _destroyResultLob($lob)
  2673.     {
  2674.         if (isset($this->lobs[$lob])) {
  2675.             $this->lobs[$lob] = '';
  2676.         }
  2677.     }
  2678.  
  2679.     // }}}
  2680.     // {{{ fetchClob()
  2681.  
  2682.     /**
  2683.      * fetch a clob value from a result set
  2684.      *
  2685.      * @param resource $result result identifier
  2686.      * @param int $row number of the row where the data can be found
  2687.      * @param int $field field number where the data can be found
  2688.      * @return mixed content of the specified data cell, a MDB error on failure,
  2689.      *        a MDB error on failure
  2690.      * @access public
  2691.      */
  2692.     function fetchClob($result, $row, $field)
  2693.     {
  2694.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2695.             'fetch clob result method is not implemented'));
  2696.     }
  2697.  
  2698.     // }}}
  2699.     // {{{ fetchBlob()
  2700.  
  2701.     /**
  2702.      * fetch a blob value from a result set
  2703.      *
  2704.      * @param resource $result result identifier
  2705.      * @param int $row number of the row where the data can be found
  2706.      * @param int $field field number where the data can be found
  2707.      * @return mixed content of the specified data cell, a MDB error on failure
  2708.      * @access public
  2709.      */
  2710.     function fetchBlob($result, $row, $field)
  2711.     {
  2712.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  2713.             'fetch blob result method is not implemented'));
  2714.     }
  2715.  
  2716.     // }}}
  2717.     // {{{ resultIsNull()
  2718.  
  2719.     /**
  2720.      * Determine whether the value of a query result located in given row and
  2721.      *    field is a NULL.
  2722.      *
  2723.      * @param resource $result result identifier
  2724.      * @param int $row number of the row where the data can be found
  2725.      * @param int $field field number where the data can be found
  2726.      * @return mixed TRUE or FALSE on success, a MDB error on failure
  2727.      * @access public
  2728.      */
  2729.     function resultIsNull($result, $row, $field)
  2730.     {
  2731.         $result = $this->fetch($result, $row, $field);
  2732.         if (MDB::isError($result)) {
  2733.             return($result);
  2734.         }
  2735.         return(!isset($result));
  2736.     }
  2737.  
  2738.     // }}}
  2739.     // {{{ _baseConvertResult()
  2740.  
  2741.     /**
  2742.      * general type conversion method
  2743.      *
  2744.      * @param mixed $value refernce to a value to be converted
  2745.      * @param int $type constant that specifies which type to convert to
  2746.      * @return object a MDB error on failure
  2747.      * @access private
  2748.      */
  2749.     function _baseConvertResult($value, $type)
  2750.     {
  2751.         switch ($type) {
  2752.             case MDB_TYPE_TEXT:
  2753.                 return($value);
  2754.             case MDB_TYPE_BLOB:
  2755.                 return($value);
  2756.             case MDB_TYPE_CLOB:
  2757.                 return($value);
  2758.             case MDB_TYPE_INTEGER:
  2759.                 return(intval($value));
  2760.             case MDB_TYPE_BOOLEAN:
  2761.                 return ($value == 'Y') ? TRUE : FALSE;
  2762.             case MDB_TYPE_DECIMAL:
  2763.                 return($value);
  2764.             case MDB_TYPE_FLOAT:
  2765.                 return(doubleval($value));
  2766.             case MDB_TYPE_DATE:
  2767.                 return($value);
  2768.             case MDB_TYPE_TIME:
  2769.                 return($value);
  2770.             case MDB_TYPE_TIMESTAMP:
  2771.                 return($value);
  2772.             case MDB_TYPE_CLOB:
  2773.                 return($value);
  2774.             case MDB_TYPE_BLOB:
  2775.                 return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  2776.                     'BaseConvertResult: attempt to convert result value to an unsupported type ' . $type));
  2777.             default:
  2778.                 return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
  2779.                     'BaseConvertResult: attempt to convert result value to an unknown type ' . $type));
  2780.         }
  2781.     }
  2782.  
  2783.     // }}}
  2784.     // {{{ convertResult()
  2785.  
  2786.     /**
  2787.      * convert a value to a RDBMS indepdenant MDB type
  2788.      *
  2789.      * @param mixed $value value to be converted
  2790.      * @param int $type constant that specifies which type to convert to
  2791.      * @return mixed converted value or a MDB error on failure
  2792.      * @access public
  2793.      */
  2794.     function convertResult($value, $type)
  2795.     {
  2796.         return($this->_baseConvertResult($value, $type));
  2797.     }
  2798.  
  2799.     // }}}
  2800.     // {{{ convertResultRow()
  2801.  
  2802.     /**
  2803.      * convert a result row
  2804.      *
  2805.      * @param resource $result result identifier
  2806.      * @param array $row array with data
  2807.      * @return mixed MDB_OK on success,  a MDB error on failure
  2808.      * @access public
  2809.      */
  2810.     function convertResultRow($result, $row)
  2811.     {
  2812.         if (isset($this->result_types[$result])) {
  2813.             $current_column = -1;
  2814.             foreach($row as $key => $column) {
  2815.                 ++$current_column;
  2816.                 if (!isset($this->result_types[$result][$current_column])
  2817.                    ||!isset($column)
  2818.                 ) {
  2819.                     continue;
  2820.                 }
  2821.                 switch ($type = $this->result_types[$result][$current_column]) {
  2822.                     case MDB_TYPE_TEXT:
  2823.                     case MDB_TYPE_BLOB:
  2824.                     case MDB_TYPE_CLOB:
  2825.                         break;
  2826.                     case MDB_TYPE_INTEGER:
  2827.                         $row[$key] = intval($row[$key]);
  2828.                         break;
  2829.                     default:
  2830.                         $value = $this->convertResult($row[$key], $type);
  2831.                         if (MDB::isError($value)) {
  2832.                             return $value;
  2833.                         }
  2834.                         $row[$key] = $value;
  2835.                         break;
  2836.                 }
  2837.             }
  2838.         }
  2839.         return ($row);
  2840.     }
  2841.  
  2842.     // }}}
  2843.     // {{{ fetchDate()
  2844.  
  2845.     /**
  2846.      * fetch a date value from a result set
  2847.      *
  2848.      * @param resource $result result identifier
  2849.      * @param int $row number of the row where the data can be found
  2850.      * @param int $field field number where the data can be found
  2851.      * @return mixed content of the specified data cell, a MDB error on failure
  2852.      * @access public
  2853.      */
  2854.     function fetchDate($result, $row, $field)
  2855.     {
  2856.         $value = $this->fetch($result, $row, $field);
  2857.         return($this->convertResult($value, MDB_TYPE_DATE));
  2858.     }
  2859.  
  2860.     // }}}
  2861.     // {{{ fetchTimestamp()
  2862.  
  2863.     /**
  2864.      * fetch a timestamp value from a result set
  2865.      *
  2866.      * @param resource $result result identifier
  2867.      * @param int $row number of the row where the data can be found
  2868.      * @param int $field field number where the data can be found
  2869.      * @return mixed content of the specified data cell, a MDB error on failure
  2870.      * @access public
  2871.      */
  2872.     function fetchTimestamp($result, $row, $field)
  2873.     {
  2874.         $value = $this->fetch($result, $row, $field);
  2875.         return($this->convertResult($value, MDB_TYPE_TIMESTAMP));
  2876.     }
  2877.  
  2878.     // }}}
  2879.     // {{{ fetchTime()
  2880.  
  2881.     /**
  2882.      * fetch a time value from a result set
  2883.      *
  2884.      * @param resource $result result identifier
  2885.      * @param int $row number of the row where the data can be found
  2886.      * @param int $field field number where the data can be found
  2887.      * @return mixed content of the specified data cell, a MDB error on failure
  2888.      * @access public
  2889.      */
  2890.     function fetchTime($result, $row, $field)
  2891.     {
  2892.         $value = $this->fetch($result, $row, $field);
  2893.         return($this->convertResult($value, MDB_TYPE_TIME));
  2894.     }
  2895.  
  2896.     // }}}
  2897.     // {{{ fetchBoolean()
  2898.  
  2899.     /**
  2900.      * fetch a boolean value from a result set
  2901.      *
  2902.      * @param resource $result result identifier
  2903.      * @param int $row number of the row where the data can be found
  2904.      * @param int $field field number where the data can be found
  2905.      * @return mixed content of the specified data cell, a MDB error on failure
  2906.      * @access public
  2907.      */
  2908.     function fetchBoolean($result, $row, $field)
  2909.     {
  2910.         $value = $this->fetch($result, $row, $field);
  2911.         return($this->convertResult($value, MDB_TYPE_BOOLEAN));
  2912.     }
  2913.  
  2914.     // }}}
  2915.     // {{{ fetchFloat()
  2916.  
  2917.     /**
  2918.      * fetch a float value from a result set
  2919.      *
  2920.      * @param resource $result result identifier
  2921.      * @param int $row number of the row where the data can be found
  2922.      * @param int $field field number where the data can be found
  2923.      * @return mixed content of the specified data cell, a MDB error on failure
  2924.      * @access public
  2925.      */
  2926.     function fetchFloat($result, $row, $field)
  2927.     {
  2928.         $value = $this->fetch($result, $row, $field);
  2929.         return($this->convertResult($value, MDB_TYPE_FLOAT));
  2930.     }
  2931.  
  2932.     // }}}
  2933.     // {{{ fetchDecimal()
  2934.  
  2935.     /**
  2936.      * fetch a decimal value from a result set
  2937.      *
  2938.      * @param resource $result result identifier
  2939.      * @param int $row number of the row where the data can be found
  2940.      * @param int $field field number where the data can be found
  2941.      * @return mixed content of the specified data cell, a MDB error on failure
  2942.      * @access public
  2943.      */
  2944.     function fetchDecimal($result, $row, $field)
  2945.     {
  2946.         $value = $this->fetch($result, $row, $field);
  2947.         return($this->convertResult($value, MDB_TYPE_DECIMAL));
  2948.     }
  2949.  
  2950.     // }}}
  2951.     // {{{ numRows()
  2952.  
  2953.     /**
  2954.      * returns the number of rows in a result object
  2955.      *
  2956.      * @param ressource $result a valid result ressouce pointer
  2957.      * @return mixed MDB_Error or the number of rows
  2958.      * @access public
  2959.      */
  2960.     function numRows($result)
  2961.     {
  2962.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Num Rows: number of rows method not implemented'));
  2963.     }
  2964.  
  2965.     // }}}
  2966.     // {{{ freeResult()
  2967.  
  2968.     /**
  2969.      * Free the internal resources associated with $result.
  2970.      *
  2971.      * @param  $result result identifier
  2972.      * @return boolean TRUE on success, FALSE if $result is invalid
  2973.      * @access public
  2974.      */
  2975.     function freeResult($result)
  2976.     {
  2977.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'Free Result: free result method not implemented'));
  2978.     }
  2979.  
  2980.     // }}}
  2981.     // {{{ getIntegerDeclaration()
  2982.  
  2983.     /**
  2984.      * Obtain DBMS specific SQL code portion needed to declare an integer type
  2985.      * field to be used in statements like CREATE TABLE.
  2986.      *
  2987.      * @param string $name name the field to be declared.
  2988.      * @param string $field associative array with the name of the properties
  2989.      *       of the field being declared as array indexes. Currently, the types
  2990.      *       of supported field properties are as follows:
  2991.      *
  2992.      *       unsigned
  2993.      *           Boolean flag that indicates whether the field should be
  2994.      *           declared as unsigned integer if possible.
  2995.      *
  2996.      *       default
  2997.      *           Integer value to be used as default for this field.
  2998.      *
  2999.      *       notnull
  3000.      *           Boolean flag that indicates whether this field is constrained
  3001.      *           to not be set to NULL.
  3002.      * @return string DBMS specific SQL code portion that should be used to
  3003.      *       declare the specified field.
  3004.      * @access public
  3005.      */
  3006.     function getIntegerDeclaration($name, $field)
  3007.     {
  3008.         if (isset($field['unsigned'])) {
  3009.             $this->warnings[] = "unsigned integer field \"$name\" is being
  3010.                 declared as signed integer";
  3011.         }
  3012.         return("$name INT" . (isset($field['default']) ? ' DEFAULT ' . $field['default'] : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3013.     }
  3014.  
  3015.     // }}}
  3016.     // {{{ getTextDeclaration()
  3017.  
  3018.     /**
  3019.      * Obtain DBMS specific SQL code portion needed to declare an text type
  3020.      * field to be used in statements like CREATE TABLE.
  3021.      *
  3022.      * @param string $name name the field to be declared.
  3023.      * @param string $field associative array with the name of the properties
  3024.      *       of the field being declared as array indexes. Currently, the types
  3025.      *       of supported field properties are as follows:
  3026.      *
  3027.      *       length
  3028.      *           Integer value that determines the maximum length of the text
  3029.      *           field. If this argument is missing the field should be
  3030.      *           declared to have the longest length allowed by the DBMS.
  3031.      *
  3032.      *       default
  3033.      *           Text value to be used as default for this field.
  3034.      *
  3035.      *       notnull
  3036.      *           Boolean flag that indicates whether this field is constrained
  3037.      *           to not be set to NULL.
  3038.      * @return string DBMS specific SQL code portion that should be used to
  3039.      *       declare the specified field.
  3040.      * @access public
  3041.      */
  3042.     function getTextDeclaration($name, $field)
  3043.     {
  3044.         return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3045.     }
  3046.  
  3047.     // }}}
  3048.     // {{{ getClobDeclaration()
  3049.  
  3050.     /**
  3051.      * Obtain DBMS specific SQL code portion needed to declare an character
  3052.      * large object type field to be used in statements like CREATE TABLE.
  3053.      *
  3054.      * @param string $name name the field to be declared.
  3055.      * @param string $field associative array with the name of the properties
  3056.      *       of the field being declared as array indexes. Currently, the types
  3057.      *       of supported field properties are as follows:
  3058.      *
  3059.      *       length
  3060.      *           Integer value that determines the maximum length of the large
  3061.      *           object field. If this argument is missing the field should be
  3062.      *           declared to have the longest length allowed by the DBMS.
  3063.      *
  3064.      *       notnull
  3065.      *           Boolean flag that indicates whether this field is constrained
  3066.      *           to not be set to NULL.
  3067.      * @return string DBMS specific SQL code portion that should be used to
  3068.      *       declare the specified field.
  3069.      * @access public
  3070.      */
  3071.     function getClobDeclaration($name, $field)
  3072.     {
  3073.         return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3074.     }
  3075.  
  3076.     // }}}
  3077.     // {{{ getBlobDeclaration()
  3078.  
  3079.     /**
  3080.      * Obtain DBMS specific SQL code portion needed to declare an binary large
  3081.      * object type field to be used in statements like CREATE TABLE.
  3082.      *
  3083.      * @param string $name name the field to be declared.
  3084.      * @param string $field associative array with the name of the properties
  3085.      *       of the field being declared as array indexes. Currently, the types
  3086.      *       of supported field properties are as follows:
  3087.      *
  3088.      *       length
  3089.      *           Integer value that determines the maximum length of the large
  3090.      *           object field. If this argument is missing the field should be
  3091.      *           declared to have the longest length allowed by the DBMS.
  3092.      *
  3093.      *       notnull
  3094.      *           Boolean flag that indicates whether this field is constrained
  3095.      *           to not be set to NULL.
  3096.      * @return string DBMS specific SQL code portion that should be used to
  3097.      *       declare the specified field.
  3098.      * @access public
  3099.      */
  3100.     function getBlobDeclaration($name, $field)
  3101.     {
  3102.         return((isset($field['length']) ? "$name CHAR (" . $field['length'] . ')' : "$name TEXT") . (isset($field['default']) ? ' DEFAULT ' . $this->getTextValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3103.     }
  3104.  
  3105.     // }}}
  3106.     // {{{ getBooleanDeclaration()
  3107.  
  3108.     /**
  3109.      * Obtain DBMS specific SQL code portion needed to declare a boolean type
  3110.      * field to be used in statements like CREATE TABLE.
  3111.      *
  3112.      * @param string $name name the field to be declared.
  3113.      * @param string $field associative array with the name of the properties
  3114.      *       of the field being declared as array indexes. Currently, the types
  3115.      *       of supported field properties are as follows:
  3116.      *
  3117.      *       default
  3118.      *           Boolean value to be used as default for this field.
  3119.      *
  3120.      *       notnullL
  3121.      *           Boolean flag that indicates whether this field is constrained
  3122.      *           to not be set to NULL.
  3123.      * @return string DBMS specific SQL code portion that should be used to
  3124.      *       declare the specified field.
  3125.      * @access public
  3126.      */
  3127.     function getBooleanDeclaration($name, $field)
  3128.     {
  3129.         return("$name CHAR (1)" . (isset($field['default']) ? ' DEFAULT ' . $this->getBooleanValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3130.     }
  3131.  
  3132.     // }}}
  3133.     // {{{ getDateDeclaration()
  3134.  
  3135.     /**
  3136.      * Obtain DBMS specific SQL code portion needed to declare a date type
  3137.      * field to be used in statements like CREATE TABLE.
  3138.      *
  3139.      * @param string $name name the field to be declared.
  3140.      * @param string $field associative array with the name of the properties
  3141.      *       of the field being declared as array indexes. Currently, the types
  3142.      *       of supported field properties are as follows:
  3143.      *
  3144.      *       default
  3145.      *           Date value to be used as default for this field.
  3146.      *
  3147.      *       notnull
  3148.      *           Boolean flag that indicates whether this field is constrained
  3149.      *           to not be set to NULL.
  3150.      * @return string DBMS specific SQL code portion that should be used to
  3151.      *       declare the specified field.
  3152.      * @access public
  3153.      */
  3154.     function getDateDeclaration($name, $field)
  3155.     {
  3156.         return("$name CHAR (" . strlen("YYYY-MM-DD") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getDateValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3157.     }
  3158.  
  3159.     // }}}
  3160.     // {{{ getTimestampDeclaration()
  3161.  
  3162.     /**
  3163.      * Obtain DBMS specific SQL code portion needed to declare a timestamp
  3164.      * field to be used in statements like CREATE TABLE.
  3165.      *
  3166.      * @param string $name name the field to be declared.
  3167.      * @param string $field associative array with the name of the properties
  3168.      *       of the field being declared as array indexes. Currently, the types
  3169.      *       of supported field properties are as follows:
  3170.      *
  3171.      *       default
  3172.      *           Timestamp value to be used as default for this field.
  3173.      *
  3174.      *       notnull
  3175.      *           Boolean flag that indicates whether this field is constrained
  3176.      *           to not be set to NULL.
  3177.      * @return string DBMS specific SQL code portion that should be used to
  3178.      *       declare the specified field.
  3179.      * @access public
  3180.      */
  3181.     function getTimestampDeclaration($name, $field)
  3182.     {
  3183.         return("$name CHAR (" . strlen("YYYY-MM-DD HH:MM:SS") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getTimestampValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3184.     }
  3185.  
  3186.     // }}}
  3187.     // {{{ getTimeDeclaration()
  3188.  
  3189.     /**
  3190.      * Obtain DBMS specific SQL code portion needed to declare a time
  3191.      * field to be used in statements like CREATE TABLE.
  3192.      *
  3193.      * @param string $name name the field to be declared.
  3194.      * @param string $field associative array with the name of the properties
  3195.      *       of the field being declared as array indexes. Currently, the types
  3196.      *       of supported field properties are as follows:
  3197.      *
  3198.      *       default
  3199.      *           Time value to be used as default for this field.
  3200.      *
  3201.      *       notnull
  3202.      *           Boolean flag that indicates whether this field is constrained
  3203.      *           to not be set to NULL.
  3204.      * @return string DBMS specific SQL code portion that should be used to
  3205.      *       declare the specified field.
  3206.      * @access public
  3207.      */
  3208.     function getTimeDeclaration($name, $field)
  3209.     {
  3210.         return("$name CHAR (" . strlen("HH:MM:SS") . ")" . (isset($field['default']) ? ' DEFAULT ' . $this->getTimeValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3211.     }
  3212.  
  3213.     // }}}
  3214.     // {{{ getFloatDeclaration()
  3215.  
  3216.     /**
  3217.      * Obtain DBMS specific SQL code portion needed to declare a float type
  3218.      * field to be used in statements like CREATE TABLE.
  3219.      *
  3220.      * @param string $name name the field to be declared.
  3221.      * @param string $field associative array with the name of the properties
  3222.      *       of the field being declared as array indexes. Currently, the types
  3223.      *       of supported field properties are as follows:
  3224.      *
  3225.      *       default
  3226.      *           Float value to be used as default for this field.
  3227.      *
  3228.      *       notnull
  3229.      *           Boolean flag that indicates whether this field is constrained
  3230.      *           to not be set to NULL.
  3231.      * @return string DBMS specific SQL code portion that should be used to
  3232.      *       declare the specified field.
  3233.      * @access public
  3234.      */
  3235.     function getFloatDeclaration($name, $field)
  3236.     {
  3237.         return("$name TEXT " . (isset($field['default']) ? ' DEFAULT ' . $this->getFloatValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3238.     }
  3239.  
  3240.     // }}}
  3241.     // {{{ getDecimalDeclaration()
  3242.  
  3243.     /**
  3244.      * Obtain DBMS specific SQL code portion needed to declare a decimal type
  3245.      * field to be used in statements like CREATE TABLE.
  3246.      *
  3247.      * @param string $name name the field to be declared.
  3248.      * @param string $field associative array with the name of the properties
  3249.      *       of the field being declared as array indexes. Currently, the types
  3250.      *       of supported field properties are as follows:
  3251.      *
  3252.      *       default
  3253.      *           Decimal value to be used as default for this field.
  3254.      *
  3255.      *       notnull
  3256.      *           Boolean flag that indicates whether this field is constrained
  3257.      *           to not be set to NULL.
  3258.      * @return string DBMS specific SQL code portion that should be used to
  3259.      *       declare the specified field.
  3260.      * @access public
  3261.      */
  3262.     function getDecimalDeclaration($name, $field)
  3263.     {
  3264.         return("$name TEXT " . (isset($field['default']) ? ' DEFAULT ' . $this->getDecimalValue($field['default']) : '') . (isset($field['notnull']) ? ' NOT NULL' : ''));
  3265.     }
  3266.  
  3267.     // }}}
  3268.     // {{{ getIntegerValue()
  3269.  
  3270.     /**
  3271.      * Convert a text value into a DBMS specific format that is suitable to
  3272.      * compose query statements.
  3273.      *
  3274.      * @param string $value text string value that is intended to be converted.
  3275.      * @return string text string that represents the given argument value in
  3276.      *       a DBMS specific format.
  3277.      * @access public
  3278.      */
  3279.     function getIntegerValue($value)
  3280.     {
  3281.         return(($value === NULL) ? 'NULL' : (int)$value);
  3282.     }
  3283.  
  3284.     // }}}
  3285.     // {{{ getTextValue()
  3286.  
  3287.     /**
  3288.      * Convert a text value into a DBMS specific format that is suitable to
  3289.      * compose query statements.
  3290.      *
  3291.      * @param string $value text string value that is intended to be converted.
  3292.      * @return string text string that already contains any DBMS specific
  3293.      *       escaped character sequences.
  3294.      * @access public
  3295.      */
  3296.     function getTextValue($value)
  3297.     {
  3298.         return(($value === NULL) ? 'NULL' : "'".$this->_quote($value)."'");
  3299.     }
  3300.  
  3301.     // }}}
  3302.     // {{{ getClobValue()
  3303.  
  3304.     /**
  3305.      * Convert a text value into a DBMS specific format that is suitable to
  3306.      * compose query statements.
  3307.      *
  3308.      * @param resource $prepared_query query handle from prepare()
  3309.      * @param  $parameter
  3310.      * @param  $clob
  3311.      * @return string text string that represents the given argument value in
  3312.      *       a DBMS specific format.
  3313.      * @access public
  3314.      */
  3315.     function getClobValue($prepared_query, $parameter, $clob)
  3316.     {
  3317.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  3318.             'Get CLOB field value: prepared queries with values of type "clob" are not yet supported'));
  3319.     }
  3320.  
  3321.     // }}}
  3322.     // {{{ freeClobValue()
  3323.  
  3324.     /**
  3325.      * free a character large object
  3326.      *
  3327.      * @param resource $prepared_query query handle from prepare()
  3328.      * @param string $blob
  3329.      * @param string $value
  3330.      * @access public
  3331.      */
  3332.     function freeClobValue($prepared_query, $clob, &$value)
  3333.     {
  3334.     }
  3335.  
  3336.     // }}}
  3337.     // {{{ getBlobValue()
  3338.  
  3339.     /**
  3340.      * Convert a text value into a DBMS specific format that is suitable to
  3341.      * compose query statements.
  3342.      *
  3343.      * @param resource $prepared_query query handle from prepare()
  3344.      * @param  $parameter
  3345.      * @param  $blob
  3346.      * @return string text string that represents the given argument value in
  3347.      *       a DBMS specific format.
  3348.      * @access public
  3349.      */
  3350.     function getBlobValue($prepared_query, $parameter, $blob)
  3351.     {
  3352.         return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
  3353.             'Get BLOB field value: prepared queries with values of type "blob" are not yet supported'));
  3354.     }
  3355.  
  3356.     // }}}
  3357.     // {{{ freeBlobValue()
  3358.  
  3359.     /**
  3360.      * free a binary large object
  3361.      *
  3362.      * @param resource $prepared_query query handle from prepare()
  3363.      * @param string $blob
  3364.      * @param string $value
  3365.      * @access public
  3366.      */
  3367.     function freeBlobValue($prepared_query, $blob, &$value)
  3368.     {
  3369.     }
  3370.  
  3371.     // }}}
  3372.     // {{{ getBooleanValue()
  3373.  
  3374.     /**
  3375.      * Convert a text value into a DBMS specific format that is suitable to
  3376.      * compose query statements.
  3377.      *
  3378.      * @param string $value text string value that is intended to be converted.
  3379.      * @return string text string that represents the given argument value in
  3380.      *       a DBMS specific format.
  3381.      * @access public
  3382.      */
  3383.     function getBooleanValue($value)
  3384.     {
  3385.         return(($value === NULL) ? 'NULL' : ($value ? "'Y'" : "'N'"));
  3386.     }
  3387.  
  3388.     // }}}
  3389.     // {{{ getDateValue()
  3390.  
  3391.     /**
  3392.      * Convert a text value into a DBMS specific format that is suitable to
  3393.      * compose query statements.
  3394.      *
  3395.      * @param string $value text string value that is intended to be converted.
  3396.      * @return string text string that represents the given argument value in
  3397.      *       a DBMS specific format.
  3398.      * @access public
  3399.      */
  3400.     function getDateValue($value)
  3401.     {
  3402.         return(($value === NULL) ? 'NULL' : "'$value'");
  3403.     }
  3404.  
  3405.     // }}}
  3406.     // {{{ getTimestampValue()
  3407.  
  3408.     /**
  3409.      * Convert a text value into a DBMS specific format that is suitable to
  3410.      * compose query statements.
  3411.      *
  3412.      * @param string $value text string value that is intended to be converted.
  3413.      * @return string text string that represents the given argument value in
  3414.      *       a DBMS specific format.
  3415.      * @access public
  3416.      */
  3417.     function getTimestampValue($value)
  3418.     {
  3419.         return(($value === NULL) ? 'NULL' : "'$value'");
  3420.     }
  3421.  
  3422.     // }}}
  3423.     // {{{ getTimeValue()
  3424.  
  3425.     /**
  3426.      * Convert a text value into a DBMS specific format that is suitable to
  3427.      *       compose query statements.
  3428.      *
  3429.      * @param string $value text string value that is intended to be converted.
  3430.      * @return string text string that represents the given argument value in
  3431.      *       a DBMS specific format.
  3432.      * @access public
  3433.      */
  3434.     function getTimeValue($value)
  3435.     {
  3436.         return(($value === NULL) ? 'NULL' : "'$value'");
  3437.     }
  3438.  
  3439.     // }}}
  3440.     // {{{ getFloatValue()
  3441.  
  3442.     /**
  3443.      * Convert a text value into a DBMS specific format that is suitable to
  3444.      * compose query statements.
  3445.      *
  3446.      * @param string $value text string value that is intended to be converted.
  3447.      * @return string text string that represents the given argument value in
  3448.      *       a DBMS specific format.
  3449.      * @access public
  3450.      */
  3451.     function getFloatValue($value)
  3452.     {
  3453.         return(($value === NULL) ? 'NULL' : "'$value'");
  3454.     }
  3455.  
  3456.     // }}}
  3457.     // {{{ getDecimalValue()
  3458.  
  3459.     /**
  3460.      * Convert a text value into a DBMS specific format that is suitable to
  3461.      * compose query statements.
  3462.      *
  3463.      * @param string $value text string value that is intended to be converted.
  3464.      * @return string text string that represents the given argument value in
  3465.      *       a DBMS specific format.
  3466.      * @access public
  3467.      */
  3468.     function getDecimalValue($value)
  3469.     {
  3470.         return(($value === NULL) ? 'NULL' : "'$value'");
  3471.     }
  3472.  
  3473.     // }}}
  3474.     // {{{ getValue()
  3475.  
  3476.     /**
  3477.      * Convert a text value into a DBMS specific format that is suitable to
  3478.      * compose query statements.
  3479.      *
  3480.      * @param string $type type to which the value should be converted to
  3481.      * @param string $value text string value that is intended to be converted.
  3482.      * @return string text string that represents the given argument value in
  3483.      *       a DBMS specific format.
  3484.      * @access public
  3485.      */
  3486.     function getValue($type, $value)
  3487.     {
  3488.         if (empty($type)) {
  3489.             return($this->raiseError(MDB_ERROR_SYNTAX, NULL, NULL,
  3490.                 'getValue: called without type to convert to'));
  3491.         }
  3492.         if (method_exists($this,"get{$type}Value")) {
  3493.             return $this->{"get{$type}Value"}($value);
  3494.         }
  3495.         return $value;
  3496.     }
  3497.  
  3498.     // }}}
  3499.     // {{{ support()
  3500.  
  3501.     /**
  3502.      * Tell whether a DB implementation or its backend extension
  3503.      * supports a given feature.
  3504.      *
  3505.      * @param string $feature name of the feature (see the MDB class doc)
  3506.      * @return boolean whether this DB implementation supports $feature
  3507.      * @access public
  3508.      */
  3509.     function support($feature)
  3510.     {
  3511.         return(isset($this->supported[$feature]) && $this->supported[$feature]);
  3512.     }
  3513.  
  3514.     // }}}
  3515.     // {{{ getSequenceName()
  3516.  
  3517.     /**
  3518.      * adds sequence name formating to a sequence name
  3519.      *
  3520.      * @param string $sqn name of the sequence
  3521.      * @return string formatted sequence name
  3522.      * @access public
  3523.      */
  3524.     function getSequenceName($sqn)
  3525.     {
  3526.         return sprintf($this->options['seqname_format'],
  3527.             preg_replace('/[^a-z0-9_]/i', '_', $sqn));
  3528.     }
  3529.  
  3530.     // }}}
  3531.     // {{{ nextId()
  3532.  
  3533.     /**
  3534.      * returns the next free id of a sequence
  3535.      *
  3536.      * @param string $seq_name name of the sequence
  3537.      * @param boolean $ondemand when TRUE the seqence is
  3538.      *                           automatic created, if it
  3539.      *                           not exists
  3540.      * @return mixed MDB_Error or id
  3541.      * @access public
  3542.      */
  3543.     function nextId($seq_name, $ondemand = FALSE)
  3544.     {
  3545.         return($this->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL,
  3546.             'Next Sequence: getting next sequence value not supported'));
  3547.     }
  3548.  
  3549.     // }}}
  3550.     // {{{ currId()
  3551.  
  3552.     /**
  3553.      * returns the current id of a sequence
  3554.      *
  3555.      * @param string $seq_name name of the sequence
  3556.      * @return mixed MDB_Error or id
  3557.      * @access public
  3558.      */
  3559.     function currId($seq_name)
  3560.     {
  3561.         $this->warnings[] = 'database does not support getting current
  3562.             sequence value, the sequence value was incremented';
  3563.         $this->expectError(MDB_ERROR_NOT_CAPABLE);
  3564.         $id = $this->nextId($seq_name);
  3565.         $this->popExpectError(MDB_ERROR_NOT_CAPABLE);
  3566.         if (MDB::isError($id)) {
  3567.             if ($id->getCode() == MDB_ERROR_NOT_CAPABLE) {
  3568.                 return($this->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL,
  3569.                     'Current Sequence: getting current sequence value not supported'));
  3570.             }
  3571.             return($id);
  3572.         }
  3573.         return($id);
  3574.     }
  3575.  
  3576.     // }}}
  3577.     // {{{ fetchInto()
  3578.  
  3579.     /**
  3580.      * Fetch a row and return data in an array.
  3581.      *
  3582.      * @param resource $result result identifier
  3583.      * @param int $fetchmode ignored
  3584.      * @param int $rownum the row number to fetch
  3585.      * @return mixed data array or NULL on success, a MDB error on failure
  3586.      * @access public
  3587.      */
  3588.     function fetchInto($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rownum = NULL)
  3589.     {
  3590.         if (MDB::isError($result)) {
  3591.             return($this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
  3592.                 'Fetch field: it was not specified a valid result set'));
  3593.         }
  3594.         if (MDB::isError($this->endOfResult($result))) {
  3595.             $this->freeResult($result);
  3596.             $result = $this->raiseError(MDB_ERROR_NEED_MORE_DATA, NULL, NULL,
  3597.                 'Fetch field: result set is empty');
  3598.         }
  3599.         if ($rownum == NULL) {
  3600.             ++$this->highest_fetched_row[$result];
  3601.             $rownum = $this->highest_fetched_row[$result];
  3602.         } else {
  3603.             $this->highest_fetched_row[$result] =
  3604.                 max($this->highest_fetched_row[$result], $row);
  3605.         }
  3606.         if ($fetchmode == MDB_FETCHMODE_DEFAULT) {
  3607.             $fetchmode = $this->fetchmode;
  3608.         }
  3609.         $columns = $this->numCols($result);
  3610.         if (MDB::isError($columns)) {
  3611.             return($columns);
  3612.         }
  3613.         if ($fetchmode & MDB_FETCHMODE_ASSOC) {
  3614.             $column_names = $this->getColumnNames($result);
  3615.         }
  3616.         for($column = 0; $column < $columns; $column++) {
  3617.             if (!$this->resultIsNull($result, $rownum, $column)) {
  3618.                 $value = $this->fetch($result, $rownum, $column);
  3619.                 if ($value === FALSE) {
  3620.                     if ($this->options['autofree']) {
  3621.                         $this->freeResult($result);
  3622.                     }
  3623.                     return(NULL);
  3624.                 } elseif (MDB::isError($value)) {
  3625.                     if ($value->getMessage() == '') {
  3626.                         if ($this->options['autofree']) {
  3627.                             $this->freeResult($result);
  3628.                         }
  3629.                         return(NULL);
  3630.                     } else {
  3631.                         return($value);
  3632.                     }
  3633.                 }
  3634.             }
  3635.             $row[$column] = $value;
  3636.         }
  3637.         if ($fetchmode & MDB_FETCHMODE_ASSOC) {
  3638.             $row = array_combine($column_names, $row);
  3639.             if (is_array($row) && $this->options['optimize'] == 'portability') {
  3640.                 $row = array_change_key_case($row, CASE_LOWER);
  3641.             }
  3642.         }
  3643.         if (isset($this->result_types[$result])) {
  3644.             $row = $this->convertResultRow($result, $row);
  3645.         }
  3646.         return($row);
  3647.     }
  3648.  
  3649.     // }}}
  3650.     // {{{ fetchOne()
  3651.  
  3652.     /**
  3653.      * Fetch and return a field of data (it uses fetchInto for that)
  3654.      *
  3655.      * @param resource $result result identifier
  3656.      * @return mixed data on success, a MDB error on failure
  3657.      * @access public
  3658.      */
  3659.     function fetchOne($result)
  3660.     {
  3661.         $row = $this->fetchInto($result, MDB_FETCHMODE_ORDERED);
  3662.         if (!$this->options['autofree'] || $row != NULL) {
  3663.             $this->freeResult($result);
  3664.         }
  3665.         if (is_array($row)) {
  3666.             return($row[0]);
  3667.         }
  3668.         return($row);
  3669.     }
  3670.  
  3671.     // }}}
  3672.     // {{{ fetchRow()
  3673.  
  3674.     /**
  3675.      * Fetch and return a row of data (it uses fetchInto for that)
  3676.      *
  3677.      * @param resource $result result identifier
  3678.      * @param int $fetchmode how the array data should be indexed
  3679.      * @param int $rownum the row number to fetch
  3680.      * @return mixed data array on success, a MDB error on failure
  3681.      * @access public
  3682.      */
  3683.     function fetchRow($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rownum = NULL)
  3684.     {
  3685.         $row = $this->fetchInto($result, $fetchmode, $rownum);
  3686.         if (!$this->options['autofree'] || $row != NULL) {
  3687.             $this->freeResult($result);
  3688.         }
  3689.         return($row);
  3690.     }
  3691.  
  3692.     // }}}
  3693.     // {{{ fetchCol()
  3694.  
  3695.     /**
  3696.      * Fetch and return a column of data (it uses fetchInto for that)
  3697.      *
  3698.      * @param resource $result result identifier
  3699.      * @param int $colnum the row number to fetch
  3700.      * @return mixed data array on success, a MDB error on failure
  3701.      * @access public
  3702.      */
  3703.     function fetchCol($result, $colnum = 0)
  3704.     {
  3705.         $fetchmode = is_numeric($colnum) ? MDB_FETCHMODE_ORDERED : MDB_FETCHMODE_ASSOC;
  3706.         $column = array();
  3707.         $row = $this->fetchInto($result, $fetchmode);
  3708.         if (is_array($row)) {
  3709.             if (isset($row[$colnum])) {
  3710.                 $column[] = $row[$colnum];
  3711.                 while (is_array($row = $this->fetchInto($result, $fetchmode))) {
  3712.                     $column[] = $row[$colnum];
  3713.                 }
  3714.             } else {
  3715.                 $this->freeResult($result);
  3716.                 return($this->raiseError(MDB_ERROR_TRUNCATED));
  3717.             }
  3718.         }
  3719.         if (!$this->options['autofree']) {
  3720.             $this->freeResult($result);
  3721.         }
  3722.         if (MDB::isError($row)) {
  3723.             return($row);
  3724.         }
  3725.         return($column);
  3726.     }
  3727.  
  3728.     // }}}
  3729.     // {{{ fetchAll()
  3730.  
  3731.     /**
  3732.      * Fetch and return a column of data (it uses fetchInto for that)
  3733.      *
  3734.      * @param resource $result result identifier
  3735.      * @param int $fetchmode how the array data should be indexed
  3736.      * @param boolean $rekey if set to TRUE, the $all will have the first
  3737.      *       column as its first dimension
  3738.      * @param boolean $force_array used only when the query returns exactly
  3739.      *       two columns. If TRUE, the values of the returned array will be
  3740.      *       one-element arrays instead of scalars.
  3741.      * @param boolean $group if TRUE, the values of the returned array is
  3742.      *       wrapped in another array.  If the same key value (in the first
  3743.      *       column) repeats itself, the values will be appended to this array
  3744.      *       instead of overwriting the existing values.
  3745.      * @return mixed data array on success, a MDB error on failure
  3746.      * @access public
  3747.      * @see getAssoc()
  3748.      */
  3749.     function fetchAll($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rekey = FALSE, $force_array = FALSE, $group = FALSE)
  3750.     {
  3751.         if ($rekey) {
  3752.             $cols = $this->numCols($result);
  3753.             if (MDB::isError($cols)) {
  3754.                 return($cols);
  3755.             }
  3756.             if ($cols < 2) {
  3757.                 return($this->raiseError(MDB_ERROR_TRUNCATED));
  3758.             }
  3759.         }
  3760.         $all = array();
  3761.         while (is_array($row = $this->fetchInto($result, $fetchmode))) {
  3762.             if ($rekey) {
  3763.                 if ($fetchmode & MDB_FETCHMODE_ASSOC) {
  3764.                     $key = reset($row);
  3765.                     unset($row[key($row)]);
  3766.                 } else {
  3767.                     $key = array_shift($row);
  3768.                 }
  3769.                 if (!$force_array && count($row) == 1) {
  3770.                     $row = array_shift($row);
  3771.                 }
  3772.                 if ($group) {
  3773.                     $all[$key][] = $row;
  3774.                 } else {
  3775.                     $all[$key] = $row;
  3776.                 }
  3777.             } else {
  3778.                 if ($fetchmode & MDB_FETCHMODE_FLIPPED) {
  3779.                     foreach ($row as $key => $val) {
  3780.                         $all[$key][] = $val;
  3781.                     }
  3782.                 } else {
  3783.                    $all[] = $row;
  3784.                 }
  3785.             }
  3786.         }
  3787.         if (!$this->options['autofree']) {
  3788.             $this->freeResult($result);
  3789.         }
  3790.         if (MDB::isError($row)) {
  3791.             return($row);
  3792.         }
  3793.         return($all);
  3794.     }
  3795.  
  3796.     // }}}
  3797.     // {{{ queryOne()
  3798.  
  3799.     /**
  3800.      * Execute the specified query, fetch the value from the first column of
  3801.      * the first row of the result set and then frees
  3802.      * the result set.
  3803.      *
  3804.      * @param string $query the SELECT query statement to be executed.
  3805.      * @param string $type optional argument that specifies the expected
  3806.      *       datatype of the result set field, so that an eventual conversion
  3807.      *       may be performed. The default datatype is text, meaning that no
  3808.      *       conversion is performed
  3809.      * @return mixed field value on success, a MDB error on failure
  3810.      * @access public
  3811.      */
  3812.     function queryOne($query, $type = NULL)
  3813.     {
  3814.         if ($type != NULL) {
  3815.             $type = array($type);
  3816.         }
  3817.         $this->setSelectedRowRange(0, 1);
  3818.         $result = $this->query($query, $type);
  3819.         if (MDB::isError($result)) {
  3820.             return($result);
  3821.         }
  3822.         return($this->fetchOne($result));
  3823.     }
  3824.  
  3825.     // }}}
  3826.     // {{{ queryRow()
  3827.  
  3828.     /**
  3829.      * Execute the specified query, fetch the values from the first
  3830.      * row of the result set into an array and then frees
  3831.      * the result set.
  3832.      *
  3833.      * @param string $query the SELECT query statement to be executed.
  3834.      * @param array $types optional array argument that specifies a list of
  3835.      *       expected datatypes of the result set columns, so that the eventual
  3836.      *       conversions may be performed. The default list of datatypes is
  3837.      *       empty, meaning that no conversion is performed.
  3838.      * @param int $fetchmode how the array data should be indexed
  3839.      * @return mixed data array on success, a MDB error on failure
  3840.      * @access public
  3841.      */
  3842.     function queryRow($query, $types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
  3843.     {
  3844.         $this->setSelectedRowRange(0, 1);
  3845.         $result = $this->query($query, $types);
  3846.         if (MDB::isError($result)) {
  3847.             return($result);
  3848.         }
  3849.         return($this->fetchRow($result, $fetchmode));
  3850.     }
  3851.  
  3852.     // }}}
  3853.     // {{{ queryCol()
  3854.  
  3855.     /**
  3856.      * Execute the specified query, fetch the value from the first column of
  3857.      * each row of the result set into an array and then frees the result set.
  3858.      *
  3859.      * @param string $query the SELECT query statement to be executed.
  3860.      * @param string $type optional argument that specifies the expected
  3861.      *       datatype of the result set field, so that an eventual conversion
  3862.      *       may be performed. The default datatype is text, meaning that no
  3863.      *       conversion is performed
  3864.      * @param int $colnum the row number to fetch
  3865.      * @return mixed data array on success, a MDB error on failure
  3866.      * @access public
  3867.      */
  3868.     function queryCol($query, $type = NULL, $colnum = 0)
  3869.     {
  3870.         if ($type != NULL) {
  3871.             $type = array($type);
  3872.         }
  3873.         $result = $this->query($query, $type);
  3874.         if (MDB::isError($result)) {
  3875.             return($result);
  3876.         }
  3877.         return($this->fetchCol($result, $colnum));
  3878.     }
  3879.  
  3880.     // }}}
  3881.     // {{{ queryAll()
  3882.  
  3883.     /**
  3884.      * Execute the specified query, fetch all the rows of the result set into
  3885.      * a two dimensional array and then frees the result set.
  3886.      *
  3887.      * @param string $query the SELECT query statement to be executed.
  3888.      * @param array $types optional array argument that specifies a list of
  3889.      *       expected datatypes of the result set columns, so that the eventual
  3890.      *       conversions may be performed. The default list of datatypes is
  3891.      *       empty, meaning that no conversion is performed.
  3892.      * @param int $fetchmode how the array data should be indexed
  3893.      * @param boolean $rekey if set to TRUE, the $all will have the first
  3894.      *       column as its first dimension
  3895.      * @param boolean $force_array used only when the query returns exactly
  3896.      *       two columns. If TRUE, the values of the returned array will be
  3897.      *       one-element arrays instead of scalars.
  3898.      * @param boolean $group if TRUE, the values of the returned array is
  3899.      *       wrapped in another array.  If the same key value (in the first
  3900.      *       column) repeats itself, the values will be appended to this array
  3901.      *       instead of overwriting the existing values.
  3902.      * @return mixed data array on success, a MDB error on failure
  3903.      * @access public
  3904.      */
  3905.     function queryAll($query, $types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT,
  3906.         $rekey = FALSE, $force_array = FALSE, $group = FALSE)
  3907.     {
  3908.         if (MDB::isError($result = $this->query($query, $types))) {
  3909.             return($result);
  3910.         }
  3911.         return($this->fetchAll($result, $fetchmode, $rekey, $force_array, $group));
  3912.     }
  3913.  
  3914.     // }}}
  3915.     // {{{ getOne()
  3916.  
  3917.     /**
  3918.      * Fetch the first column of the first row of data returned from
  3919.      * a query.  Takes care of doing the query and freeing the results
  3920.      * when finished.
  3921.      *
  3922.      * @param string $query the SQL query
  3923.      * @param string $type string that contains the type of the column in the
  3924.      *       result set
  3925.      * @param array $params if supplied, prepare/execute will be used
  3926.      *       with this array as execute parameters
  3927.      * @param array $param_types array that contains the types of the values
  3928.      *       defined in $params
  3929.      * @return mixed MDB_Error or the returned value of the query
  3930.      * @access public
  3931.      */
  3932.     function getOne($query, $type = NULL, $params = array(), $param_types = NULL)
  3933.     {
  3934.         if ($type != NULL) {
  3935.             $type = array($type);
  3936.         }
  3937.         settype($params, 'array');
  3938.         $this->setSelectedRowRange(0, 1);
  3939.         if (count($params) > 0) {
  3940.             $prepared_query = $this->prepareQuery($query);
  3941.             if (MDB::isError($prepared_query)) {
  3942.                 return($prepared_query);
  3943.             }
  3944.             $this->setParamArray($prepared_query, $params, $param_types);
  3945.             $result = $this->executeQuery($prepared_query, $type);
  3946.         } else {
  3947.             $result = $this->query($query, $type);
  3948.         }
  3949.  
  3950.         if (MDB::isError($result)) {
  3951.             return($result);
  3952.         }
  3953.  
  3954.         $value = $this->fetchOne($result, MDB_FETCHMODE_ORDERED);
  3955.         if (MDB::isError($value)) {
  3956.             return($value);
  3957.         }
  3958.         if (isset($prepared_query)) {
  3959.             $result = $this->freePreparedQuery($prepared_query);
  3960.             if (MDB::isError($result)) {
  3961.                 return($result);
  3962.             }
  3963.         }
  3964.  
  3965.         return($value);
  3966.     }
  3967.  
  3968.     // }}}
  3969.     // {{{ getRow()
  3970.  
  3971.     /**
  3972.      * Fetch the first row of data returned from a query.  Takes care
  3973.      * of doing the query and freeing the results when finished.
  3974.      *
  3975.      * @param string $query the SQL query
  3976.      * @param array $types array that contains the types of the columns in
  3977.      *       the result set
  3978.      * @param array $params array if supplied, prepare/execute will be used
  3979.      *       with this array as execute parameters
  3980.      * @param array $param_types array that contains the types of the values
  3981.      *       defined in $params
  3982.      * @param integer $fetchmode the fetch mode to use
  3983.      * @return array the first row of results as an array indexed from
  3984.      * 0, or a MDB error code.
  3985.      * @access public
  3986.      */
  3987.     function getRow($query, $types = NULL, $params = array(), $param_types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
  3988.     {
  3989.         settype($params, 'array');
  3990.         $this->setSelectedRowRange(0, 1);
  3991.         if (count($params) > 0) {
  3992.             $prepared_query = $this->prepareQuery($query);
  3993.             if (MDB::isError($prepared_query)) {
  3994.                 return($prepared_query);
  3995.             }
  3996.             $this->setParamArray($prepared_query, $params, $param_types);
  3997.             $result = $this->executeQuery($prepared_query, $types);
  3998.         } else {
  3999.             $result = $this->query($query, $types);
  4000.         }
  4001.  
  4002.         if (MDB::isError($result)) {
  4003.             return($result);
  4004.         }
  4005.  
  4006.         $row = $this->fetchRow($result, $fetchmode);
  4007.         if (MDB::isError($row)) {
  4008.             return($row);
  4009.         }
  4010.         if (isset($prepared_query)) {
  4011.             $result = $this->freePreparedQuery($prepared_query);
  4012.             if (MDB::isError($result)) {
  4013.                 return($result);
  4014.             }
  4015.         }
  4016.  
  4017.         return($row);
  4018.     }
  4019.  
  4020.     // }}}
  4021.     // {{{ getCol()
  4022.  
  4023.     /**
  4024.      * Fetch a single column from a result set and return it as an
  4025.      * indexed array.
  4026.      *
  4027.      * @param string $query the SQL query
  4028.      * @param string $type string that contains the type of the column in the
  4029.      *       result set
  4030.      * @param array $params array if supplied, prepare/execute will be used
  4031.      *       with this array as execute parameters
  4032.      * @param array $param_types array that contains the types of the values
  4033.      *       defined in $params
  4034.      * @param mixed $colnum which column to return(integer [column number,
  4035.      *       starting at 0] or string [column name])
  4036.      * @return array an indexed array with the data from the first
  4037.      * row at index 0, or a MDB error code.
  4038.      * @access public
  4039.      */
  4040.     function getCol($query, $type = NULL, $params = array(), $param_types = NULL, $colnum = 0)
  4041.     {
  4042.         if ($type != NULL) {
  4043.             $type = array($type);
  4044.         }
  4045.         settype($params, 'array');
  4046.         if (count($params) > 0) {
  4047.             $prepared_query = $this->prepareQuery($query);
  4048.  
  4049.             if (MDB::isError($prepared_query)) {
  4050.                 return($prepared_query);
  4051.             }
  4052.             $this->setParamArray($prepared_query, $params, $param_types);
  4053.             $result = $this->executeQuery($prepared_query, $type);
  4054.         } else {
  4055.             $result = $this->query($query, $type);
  4056.         }
  4057.  
  4058.         if (MDB::isError($result)) {
  4059.             return($result);
  4060.         }
  4061.  
  4062.         $col = $this->fetchCol($result, $colnum);
  4063.         if (MDB::isError($col)) {
  4064.             return($col);
  4065.         }
  4066.         if (isset($prepared_query)) {
  4067.             $result = $this->freePreparedQuery($prepared_query);
  4068.             if (MDB::isError($result)) {
  4069.                 return($result);
  4070.             }
  4071.         }
  4072.         return($col);
  4073.     }
  4074.  
  4075.     // }}}
  4076.     // {{{ getAssoc()
  4077.  
  4078.     /**
  4079.      * Fetch the entire result set of a query and return it as an
  4080.      * associative array using the first column as the key.
  4081.      *
  4082.      * If the result set contains more than two columns, the value
  4083.      * will be an array of the values from column 2-n.  If the result
  4084.      * set contains only two columns, the returned value will be a
  4085.      * scalar with the value of the second column (unless forced to an
  4086.      * array with the $force_array parameter).  A MDB error code is
  4087.      * returned on errors.  If the result set contains fewer than two
  4088.      * columns, a MDB_ERROR_TRUNCATED error is returned.
  4089.      *
  4090.      * For example, if the table 'mytable' contains:
  4091.      *
  4092.      *   ID      TEXT       DATE
  4093.      * --------------------------------
  4094.      *   1       'one'      944679408
  4095.      *   2       'two'      944679408
  4096.      *   3       'three'    944679408
  4097.      *
  4098.      * Then the call getAssoc('SELECT id,text FROM mytable') returns:
  4099.      *    array(
  4100.      *      '1' => 'one',
  4101.      *      '2' => 'two',
  4102.      *      '3' => 'three',
  4103.      *    )
  4104.      *
  4105.      * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
  4106.      *    array(
  4107.      *      '1' => array('one', '944679408'),
  4108.      *      '2' => array('two', '944679408'),
  4109.      *      '3' => array('three', '944679408')
  4110.      *    )
  4111.      *
  4112.      * If the more than one row occurs with the same value in the
  4113.      * first column, the last row overwrites all previous ones by
  4114.      * default.  Use the $group parameter if you don't want to
  4115.      * overwrite like this.  Example:
  4116.      *
  4117.      * getAssoc('SELECT category,id,name FROM mytable', NULL, NULL
  4118.      *           MDB_FETCHMODE_ASSOC, FALSE, TRUE) returns:
  4119.      *    array(
  4120.      *      '1' => array(array('id' => '4', 'name' => 'number four'),
  4121.      *                   array('id' => '6', 'name' => 'number six')
  4122.      *             ),
  4123.      *      '9' => array(array('id' => '4', 'name' => 'number four'),
  4124.      *                   array('id' => '6', 'name' => 'number six')
  4125.      *             )
  4126.      *    )
  4127.      *
  4128.      * Keep in mind that database functions in PHP usually return string
  4129.      * values for results regardless of the database's internal type.
  4130.      *
  4131.      * @param string $query the SQL query
  4132.      * @param array $types array that contains the types of the columns in
  4133.      *       the result set
  4134.      * @param array $params array if supplied, prepare/execute will be used
  4135.      *       with this array as execute parameters
  4136.      * @param array $param_types array that contains the types of the values
  4137.      *       defined in $params
  4138.      * @param boolean $force_array used only when the query returns
  4139.      * exactly two columns.  If TRUE, the values of the returned array
  4140.      * will be one-element arrays instead of scalars.
  4141.      * @param boolean $group if TRUE, the values of the returned array
  4142.      *       is wrapped in another array.  If the same key value (in the first
  4143.      *       column) repeats itself, the values will be appended to this array
  4144.      *       instead of overwriting the existing values.
  4145.      * @return array associative array with results from the query.
  4146.      * @access public
  4147.      */
  4148.     function getAssoc($query, $types = NULL, $params = array(), $param_types = NULL,
  4149.         $fetchmode = MDB_FETCHMODE_ORDERED, $force_array = FALSE, $group = FALSE)
  4150.     {
  4151.         settype($params, 'array');
  4152.         if (count($params) > 0) {
  4153.             $prepared_query = $this->prepareQuery($query);
  4154.  
  4155.             if (MDB::isError($prepared_query)) {
  4156.                 return($prepared_query);
  4157.             }
  4158.             $this->setParamArray($prepared_query, $params, $param_types);
  4159.             $result = $this->executeQuery($prepared_query, $types);
  4160.         } else {
  4161.             $result = $this->query($query, $types);
  4162.         }
  4163.  
  4164.         if (MDB::isError($result)) {
  4165.             return($result);
  4166.         }
  4167.  
  4168.         $all = $this->fetchAll($result, $fetchmode, TRUE, $force_array, $group);
  4169.         if (MDB::isError($all)) {
  4170.             return($all);
  4171.         }
  4172.         if (isset($prepared_query)) {
  4173.             $result = $this->freePreparedQuery($prepared_query);
  4174.             if (MDB::isError($result)) {
  4175.                 return($result);
  4176.             }
  4177.         }
  4178.         return($all);
  4179.     }
  4180.  
  4181.     // }}}
  4182.     // {{{ getAll()
  4183.  
  4184.     /**
  4185.      * Fetch all the rows returned from a query.
  4186.      *
  4187.      * @param string $query the SQL query
  4188.      * @param array $types array that contains the types of the columns in
  4189.      *       the result set
  4190.      * @param array $params array if supplied, prepare/execute will be used
  4191.      *       with this array as execute parameters
  4192.      * @param array $param_types array that contains the types of the values
  4193.      *       defined in $params
  4194.      * @param integer $fetchmode the fetch mode to use
  4195.      * @return array an nested array, or a MDB error
  4196.      * @access public
  4197.      */
  4198.     function getAll($query, $types = NULL, $params = array(), $param_types = NULL, $fetchmode = MDB_FETCHMODE_DEFAULT)
  4199.     {
  4200.         settype($params, 'array');
  4201.         if (count($params) > 0) {
  4202.             $prepared_query = $this->prepareQuery($query);
  4203.  
  4204.             if (MDB::isError($prepared_query)) {
  4205.                 return($prepared_query);
  4206.             }
  4207.             $this->setParamArray($prepared_query, $params, $param_types);
  4208.             $result = $this->executeQuery($prepared_query, $types);
  4209.         } else {
  4210.             $result = $this->query($query, $types);
  4211.         }
  4212.  
  4213.         if (MDB::isError($result)) {
  4214.             return($result);
  4215.         }
  4216.  
  4217.         $all = $this->fetchAll($result, $fetchmode);
  4218.         if (MDB::isError($all)) {
  4219.             return($all);
  4220.         }
  4221.         if (isset($prepared_query)) {
  4222.             $result = $this->freePreparedQuery($prepared_query);
  4223.             if (MDB::isError($result)) {
  4224.                 return($result);
  4225.             }
  4226.         }
  4227.         return($all);
  4228.     }
  4229.  
  4230.     // }}}
  4231.     // {{{ tableInfo()
  4232.  
  4233.     /**
  4234.      * returns meta data about the result set
  4235.      *
  4236.      * @param resource $result result identifier
  4237.      * @param mixed $mode depends on implementation
  4238.      * @return array an nested array, or a MDB error
  4239.      * @access public
  4240.      */
  4241.     function tableInfo($result, $mode = NULL)
  4242.     {
  4243.         return($this->raiseError(MDB_ERROR_NOT_CAPABLE));
  4244.     }
  4245.  
  4246.     // }}}
  4247.     // {{{ createLob()
  4248.  
  4249.     /**
  4250.      * Create a handler object of a specified class with functions to
  4251.      * retrieve data from a large object data stream.
  4252.      *
  4253.      * @param array $arguments An associative array with parameters to create
  4254.      *                  the handler object. The array indexes are the names of
  4255.      *                  the parameters and the array values are the respective
  4256.      *                  parameter values.
  4257.      *
  4258.      *                  Some parameters are specific of the class of each type
  4259.      *                  of handler object that is created. The following
  4260.      *                  parameters are common to all handler object classes:
  4261.      *
  4262.      *                  Type
  4263.      *
  4264.      *                      Name of the type of the built-in supported class
  4265.      *                      that will be used to create the handler object.
  4266.      *                      There are currently four built-in types of handler
  4267.      *                      object classes: data, resultlob, inputfile and
  4268.      *                      outputfile.
  4269.      *
  4270.      *                      The data handler class is the default class. It
  4271.      *                      simply reads data from a given data string.
  4272.      *
  4273.      *                      The resultlob handler class is meant to read data
  4274.      *                      from a large object retrieved from a query result.
  4275.      *                      This class is not used directly by applications.
  4276.      *
  4277.      *                      The inputfile handler class is meant to read data
  4278.      *                      from a file to use in prepared queries with large
  4279.      *                      object field parameters.
  4280.      *
  4281.      *                      The outputfile handler class is meant to write to
  4282.      *                      a file data from result columns with large object
  4283.      *                      fields. The functions to read from this type of
  4284.      *                      large object do not return any data. Instead, the
  4285.      *                      data is just written to the output file with the
  4286.      *                      data retrieved from a specified large object handle.
  4287.      *
  4288.      *                  Class
  4289.      *
  4290.      *                      Name of the class of the handler object that will be
  4291.      *                      created if the Type argument is not specified. This
  4292.      *                      argument should be used when you need to specify a
  4293.      *                      custom handler class.
  4294.      *
  4295.      *                  Database
  4296.      *
  4297.      *                      Database object as returned by MDB::connect.
  4298.      *                      This is an option argument needed by some handler
  4299.      *                      classes like resultlob.
  4300.      *
  4301.      *                  The following arguments are specific of the inputfile
  4302.      *                  handler class:
  4303.      *
  4304.      *                      File
  4305.      *
  4306.      *                          Integer handle value of a file already opened
  4307.      *                          for writing.
  4308.      *
  4309.      *                      FileName
  4310.      *
  4311.      *                          Name of a file to be opened for writing if the
  4312.      *                          File argument is not specified.
  4313.      *
  4314.      *                  The following arguments are specific of the outputfile
  4315.      *                  handler class:
  4316.      *
  4317.      *                      File
  4318.      *
  4319.      *                          Integer handle value of a file already opened
  4320.      *                          for writing.
  4321.      *
  4322.      *                      FileName
  4323.      *
  4324.      *                          Name of a file to be opened for writing if the
  4325.      *                          File argument is not specified.
  4326.      *
  4327.      *                      BufferLength
  4328.      *
  4329.      *                          Integer value that specifies the length of a
  4330.      *                          buffer that will be used to read from the
  4331.      *                          specified large object.
  4332.      *
  4333.      *                      LOB
  4334.      *
  4335.      *                          Integer handle value that specifies a large
  4336.      *                          object from which the data to be stored in the
  4337.      *                          output file will be written.
  4338.      *
  4339.      *                      Result
  4340.      *
  4341.      *                          Integer handle value as returned by the function
  4342.      *                          MDB::query() or MDB::executeQuery() that specifies
  4343.      *                          the result set that contains the large object value
  4344.      *                          to be retrieved. If the LOB argument is specified,
  4345.      *                          this argument is ignored.
  4346.      *
  4347.      *                      Row
  4348.      *
  4349.      *                          Integer value that specifies the number of the
  4350.      *                          row of the result set that contains the large
  4351.      *                          object value to be retrieved. If the LOB
  4352.      *                          argument is specified, this argument is ignored.
  4353.      *
  4354.      *                      Field
  4355.      *
  4356.      *                          Integer or string value that specifies the
  4357.      *                          number or the name of the column of the result
  4358.      *                          set that contains the large object value to be
  4359.      *                          retrieved. If the LOB argument is specified,
  4360.      *                          this argument is ignored.
  4361.      *
  4362.      *                      Binary
  4363.      *
  4364.      *                          Boolean value that specifies whether the large
  4365.      *                          object column to be retrieved is of binary type
  4366.      *                          (blob) or otherwise is of character type (clob).
  4367.      *                          If the LOB argument is specified, this argument
  4368.      *                          is ignored.
  4369.      *
  4370.      *                  The following argument is specific of the data
  4371.      *                  handler class:
  4372.      *
  4373.      *                  Data
  4374.      *
  4375.      *                      String of data that will be returned by the class
  4376.      *                      when it requested with the readLOB() method.
  4377.      *
  4378.      *                  The following argument is specific of the resultlob
  4379.      *                  handler class:
  4380.      *
  4381.      *                      ResultLOB
  4382.      *
  4383.      *                          Integer handle value of a large object result
  4384.      *                          row field.
  4385.      * @return integer handle value that should be passed as argument insubsequent
  4386.      * calls to functions that retrieve data from the large object input stream.
  4387.      * @access public
  4388.      */
  4389.     function createLob($arguments)
  4390.     {
  4391.         $result = $this->loadLob('Create LOB');
  4392.         if (MDB::isError($result)) {
  4393.             return($result);
  4394.         }
  4395.         $class_name = 'MDB_LOB';
  4396.         if (isset($arguments['Type'])) {
  4397.             switch ($arguments['Type']) {
  4398.                 case 'data':
  4399.                     break;
  4400.                 case 'resultlob':
  4401.                     $class_name = 'MDB_LOB_Result';
  4402.                     break;
  4403.                 case 'inputfile':
  4404.                     $class_name = 'MDB_LOB_Input_File';
  4405.                     break;
  4406.                 case 'outputfile':
  4407.                     $class_name = 'MDB_LOB_Output_File';
  4408.                     break;
  4409.                 default:
  4410.                     if (isset($arguments['Error'])) {
  4411.                         $arguments['Error'] = $arguments['Type'] . ' is not a valid type of large object';
  4412.                     }
  4413.                     return($this->raiseError());
  4414.             }
  4415.         } else {
  4416.             if (isset($arguments['Class'])) {
  4417.                 $class = $arguments['Class'];
  4418.             }
  4419.         }
  4420.         $lob = count($GLOBALS['_MDB_lobs']) + 1;
  4421.         $GLOBALS['_MDB_lobs'][$lob] = &new $class_name;
  4422.         if (isset($arguments['Database'])) {
  4423.             $GLOBALS['_MDB_lobs'][$lob]->database = $arguments['Database'];
  4424.         } else {
  4425.             $GLOBALS['_MDB_lobs'][$lob]->database = &$this;
  4426.         }
  4427.         if (MDB::isError($result = $GLOBALS['_MDB_lobs'][$lob]->create($arguments))) {
  4428.             $GLOBALS['_MDB_lobs'][$lob]->database->destroyLob($lob);
  4429.             return($result);
  4430.         }
  4431.         return($lob);
  4432.     }
  4433.  
  4434.     // }}}
  4435.     // {{{ readLob()
  4436.  
  4437.     /**
  4438.      * Read data from large object input stream.
  4439.      *
  4440.      * @param integer $lob argument handle that is returned by the
  4441.      *                          MDB::createLob() method.
  4442.      * @param string $data reference to a variable that will hold data
  4443.      *                          to be read from the large object input stream
  4444.      * @param integer $length    value that indicates the largest ammount ofdata
  4445.      *                          to be read from the large object input stream.
  4446.      * @return mixed the effective number of bytes read from the large object
  4447.      *                      input stream on sucess or an MDB error object.
  4448.      * @access public
  4449.      * @see endOfLob()
  4450.      */
  4451.     function readLob($lob, &$data, $length)
  4452.     {
  4453.         return($GLOBALS['_MDB_lobs'][$lob]->readLob($data, $length));
  4454.     }
  4455.  
  4456.     // }}}
  4457.     // {{{ endOfLob()
  4458.  
  4459.     /**
  4460.      * Determine whether it was reached the end of the large object and
  4461.      * therefore there is no more data to be read for the its input stream.
  4462.      *
  4463.      * @param integer $lob argument handle that is returned by the
  4464.      *                          MDB::createLob() method.
  4465.      * @access public
  4466.      * @return boolean flag that indicates whether it was reached the end of the large object input stream
  4467.      */
  4468.     function endOfLob($lob)
  4469.     {
  4470.         return($GLOBALS['_MDB_lobs'][$lob]->endOfLob());
  4471.     }
  4472.  
  4473.     // }}}
  4474.     // {{{ destroyLob()
  4475.  
  4476.     /**
  4477.      * Free any resources allocated during the lifetime of the large object
  4478.      * handler object.
  4479.      *
  4480.      * @param integer $lob argument handle that is returned by the
  4481.      *                          MDB::createLob() method.
  4482.      * @access public
  4483.      */
  4484.     function destroyLob($lob)
  4485.     {
  4486.         $GLOBALS['_MDB_lobs'][$lob]->destroy();
  4487.         unset($GLOBALS['_MDB_lobs'][$lob]);
  4488.     }
  4489.  
  4490.     // }}}
  4491.     // {{{ Destructor
  4492.  
  4493.     /**
  4494.     * this function closes open transactions to be executed at shutdown
  4495.     *
  4496.     * @access private
  4497.     */
  4498.     function _MDB_Common()
  4499.     {
  4500.         if ($this->in_transaction && !MDB::isError($this->rollback())) {
  4501.             $this->autoCommit(TRUE);
  4502.         }
  4503.     }
  4504. };
  4505.  
  4506. // Used by many drivers
  4507. if (!function_exists('array_change_key_case')) {
  4508.     define('CASE_UPPER', 1);
  4509.     define('CASE_LOWER', 0);
  4510.     function &array_change_key_case(&$array, $case)
  4511.     {
  4512.         $casefunc = ($case == CASE_LOWER) ? 'strtolower' : 'strtoupper';
  4513.         $ret = array();
  4514.         foreach ($array as $key => $value) {
  4515.             $ret[$casefunc($key)] = $value;
  4516.         }
  4517.         return($ret);
  4518.     }
  4519. }
  4520.  
  4521. ?>
  4522.